aop在源码之前的一些了解

it2025-02-16  29

AspectJ 可以实现aop SpringAop也可以实现aop SpringAop借助了AspectJ的语法,但是他们的技术其实是有天壤之别;

<aop:aspectj-autoproxy/>

@EnableAspectJAutoProxy 开启spring对AspectJ语法的支持 @Aspect 声明切面,在AspectJ包下面 @Pointcut 声明切点,找到方法

连接点表示单个方法,这些方法组成的就是叫做切点;

AOP演变过程: Spring 1.2基于接口的配置:最早的Spring AOP是完全基于几个接口的; 最早没有引入aspectJ的时候 例子:这边写了个前置通知,环绕通知,及通知的使用;

//前置通知 public class TulingLogAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { String methodName = method.getName(); System.out.println("执行目标方法【"+methodName+"】的<前置通知>,入参"+ Arrays.asList(args)); } } //环绕通知 public class TulingLogInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println(getClass()+"调用方法前"); Object ret=invocation.proceed(); System.out.println(getClass()+"调用方法后"); return ret; } } //早期使用aop,都需要手动的调用 @Bean public ProxyFactoryBean calculateProxy(){ ProxyFactoryBean userService=new ProxyFactoryBean(); userService.setInterceptorNames("tulingLogAdvice","tulingLogInterceptor"); // 根据指定的顺序执行 userService.setTarget(tulingCalculate()); return userService; }

把通知放到责任链中,保证责任链上使用的是同一个接口, 在责任链中依次调用(遍历或递归之类的方法)前置通知,后置通知,返回通知等等; 1、统一的抽象; 2、递推或者循环调用;

spring1.2缺点:每个增强都要写一个类继承相应的接口,粒度只到类的级别,每次调用都要重新写; Advusor按照方法名做匹配;

例子:这里更加细粒度的控制了div的方法进行aop增强;

/** * Advisor 种类很多: * RegexpMethodPointcutAdvisor 按正则匹配类 * NameMatchMethodPointcutAdvisor 按方法名匹配 * DefaultBeanFactoryPointcutAdvisor xml解析的Advisor <aop:before * InstantiationModelAwarePointcutAdvisorImpl 注解解析的advisor(@Before @After....) * @return * */ @Bean public NameMatchMethodPointcutAdvisor tulingLogAspectAdvisor() { NameMatchMethodPointcutAdvisor advisor=new NameMatchMethodPointcutAdvisor(); // 通知(Advice) :是我们的通知类 // 通知者(Advisor):是经过包装后的细粒度控制方式。 advisor.setAdvice(tulingLogAdvice()); advisor.setMappedNames("div"); return advisor; } @Bean public ProxyFactoryBean calculateProxy(){ ProxyFactoryBean userService=new ProxyFactoryBean(); userService.setInterceptorNames("tulingLogAspectAdvisor"); userService.setTarget(tulingCalculate()); return userService; } // 被代理对象 @Bean public Calculate tulingCalculate() { return new TulingCalculate(); } @Component public class TulingCalculate implements Calculate { public int div(int numA, int numB) { System.out.println("执行目标方法:div"); return numA/numB; } }

这里我们增强方法tulingCalculate();在tulingCalculate()方法中我们 new TulingCalculate()这个对象;并且定义了增强div方法,因此这里TulingCalculate()对象中div方法会被增强; advisor.setMappedNames(“div*”);//如果这样配置加个*就可以是以div开头的方法做动态代理;

纯注解方式aop实现原理 找到我们所有@AspectJ的类生成Advisor的实现类; (@AspectJ的类中的@before,@affter,@AfterReturning, @AfterThrowing都是封装成了Advisor的实现类;有了 advior就有了增强的方法,在我们后置处理器中生成的) 拿到所有的bean定义是不是标记了@AspectJ,每一个通知(@before,@affter)都会生成一个Advisor;

最新回复(0)