作者简介:zhz小白
公众号:小白的Java进阶之路
专业技能:
1、Java基础,并精通多线程的开发,熟悉JVM原理
2、熟悉Java基础,并精通多线程的开发,熟悉JVM原理,具备⼀定的线上调优经验
3、熟悉MySQL数据库调优,索引原理等,⽇志原理等,并且有出过⼀篇专栏
4、了解计算机⽹络,对TCP协议,滑动窗⼝原理等有⼀定了解
5、熟悉Spring,Spring MVC,Mybatis,阅读过部分Spring源码
6、熟悉SpringCloud Alibaba体系,阅读过Nacos,Sentinel,Seata,Dubbo,Feign,Gateway核⼼源码与设计,⼆次开发能⼒
7、熟悉消息队列(Kafka,RocketMQ)的原理与设计
8、熟悉分库分表ShardingSphere,具有真实⽣产的数据迁移经验
9、熟悉分布式缓存中间件Redis,对其的核⼼数据结构,部署架构,⾼并发问题解决⽅案有⼀定的积累
10、熟悉常⽤设计模式,并运⽤于实践⼯作中
11、了解ElasticSearch,对其核⼼的原理有⼀定的了解
12、了解K8s,Jekins,GitLab
13、了解VUE,GO
14、⽬前有正在利⽤闲暇时间做互游游戏,开发、运维、运营、推销等
本人著作git项目:https://gitee.com/zhouzhz/star-jersey-platform,有兴趣的可以私聊博主一起编写,或者给颗star
领域:对支付(FMS,FUND,PAY),订单(OMS),出行行业等有相关的开发领域
如果此文还不错的话,还请关注、点赞、收藏三连支持一下博主~
名称 | 说明 |
---|---|
Joinpoint(连接点) | 指能被拦截到的点,在Spring中只有方法能被拦截。 |
Pointcut(切点) | 指要对哪些连接点进行拦截,即被增强的方法。 |
Advice(通知) | 指拦截后要做的事情,即切点被拦截后执行的方法。 |
Aspect(切面) | 切点+通知称为切面 |
Target(目标) | 被代理的对象 |
Proxy(代理) | 代理对象 |
Weaving(织入) | 生成代理对象的过程 |
package com.zhz.aspect;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import java.util.Date;
/**
* @author zhouhengzhe
* @date 2022/11/19
*/
@Slf4j
@Aspect
public class AopAspect {
/**
* 指定切面的切入点
*/
@Pointcut("execution(* com.zhz.dao.BookDao.*(..))")
public void pointCut() {
}
/**
* 前置通知:执行目标方法前 触发
*/
@Before("pointCut()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("当前时间为:"+(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"))+",前置通知——方法名:"+joinPoint.getSignature().getName()+",参数:"+JSON.toJSONString(joinPoint.getArgs()));
}
/**
* 后置通知:执行目标方法后触发
*/
@After(value = "pointCut()")
public void logAfter(JoinPoint joinPoint) {
System.out.println("当前时间为:"+(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"))+",后置通知——方法名:"+joinPoint.getSignature().getName()+",参数:"+JSON.toJSONString(joinPoint.getArgs()));
}
/**
* 返回通知:目标方法执行完并返回参数后触发。
*/
@AfterReturning(value = "pointCut()", returning = "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
System.out.println("当前时间为:"+(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"))+",返回通知——方法名:"+joinPoint.getSignature().getName()+",参数:"+JSON.toJSONString(joinPoint.getArgs())+"返回结果:"+ JSON.toJSONString(result));
}
/**
* 异常通知:目标方法抛出异常后触发
*/
@AfterThrowing(value = "pointCut()", throwing = "ex")
public void logAfterThrowing(JoinPoint joinPoint, Exception ex) {
System.out.println("当前时间为:"+(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"))+",异常通知——方法名:"+joinPoint.getSignature().getName()+",参数:"+JSON.toJSONString(joinPoint.getArgs())+",异常信息:" + ex.getMessage());
}
/**
* 环绕通知,围绕着方法执行
* 环绕通知需要携带ProceedingJoinPoint类型的参数
* 环绕通知类似于动态代理的全过程:ProceedingJoinPoint类型的参数可以决定是否执行目标方法。
* 而且环绕通知必须有返回值,返回值即为目标方法的返回值
*/
@Around(value = "pointCut()")
public Object logAround(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("当前时间为:"+(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"))+",环绕通知前——方法名:"+proceedingJoinPoint.getSignature().getName()+",参数:"+JSON.toJSONString(proceedingJoinPoint.getArgs()));
Object result = null;
//执行目标方法
try {
result = proceedingJoinPoint.proceed();
System.out.println("环绕后");
} catch (Throwable e) {
System.out.println("环绕异常后");
throw new RuntimeException(e);
}
return result;
}
}
package com.zhz.dao;
import org.springframework.stereotype.Repository;
/**
* @author zhouhengzhe
* @description: todo
* @date 2022/11/4 10:56
* @since v1
*/
@Repository
public class BookDao {
public void add(){
System.out.println("新增图书");
}
public void delete(){
System.out.println("删除图书");
}
public void update(){
System.out.println("更新图书");
}
}
package com.zhz.config;
import com.zhz.aspect.AopAspect;
import com.zhz.dao.BookDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* @author zhouhengzhe
* @description: todo
* @date 2022/11/4 10:27
* @since v1
*/
@EnableAspectJAutoProxy
@Configuration
public class MainConfig {
@Bean
public BookDao bookDao(){
return new BookDao();
}
// 将切面类加入到容器中
@Bean
public AopAspect aopAspect() {
return new AopAspect();
}
}
@Test
public void test4(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
BookDao bean = applicationContext.getBean(BookDao.class);
bean.add();
applicationContext.close();
}
通知类型 | 描述 |
---|---|
前置通知 | 在方法执行前添加功能 |
后置通知 | 在方法正常执行后添加功能 |
异常通知 | 在方法抛出异常后添加功能 |
最终通知 | 无论方法是否抛出异常,都会执行该通知 |
环绕通知 | 在方法执行前后添加功能 |
使用AspectJ需要使用切点表达式配置切点位置,写法如下: