2w字搞懂Spring AOP的前世今生(三)
Spring AOP自动动态代理的实现方式
如果让你实现对象的自动代理,你会怎么做呢?
当然是通过BeanPostProcessor来干预Bean的声明周期,聪明!Spring就是这么干的,来验证一下我们的想法
看这个类的继承关系,基本上就验证了我们的想法了。我们只要看看他重写了BeanPostProcessor的哪些方法即可?
「AbstractAutoProxyCreator重写了如下2个重要的方法」
postProcessBeforeInstantiation(Bean实例化前阶段执行)
postProcessAfterInitialization(Bean初始化后阶段执行)
「postProcessBeforeInstantiation(Bean实例化前阶段执行)」
当用户自定义了TargetSource的实现时,会从TargetSource中获取目标对象生成代理。但是一般情况下我们很少会自定义TargetSource的实现。所以这部分就不再分析了。直接看postProcessAfterInitialization
「postProcessAfterInitialization(Bean初始化后阶段执行)」
如果没有经过代理的化就会进入wrapIfNecessary方法
思路很简单,就是根据Bean获取对应的Advisor,然后创建其代理对象,并返回。
「所以当面试官问你Spring AOP和IOC是如何结合在一起的时候,你是不是知道该如何回答了?」
在Bean生命周期的Bean初始化后阶段,如果这个Bean需要增加横切逻辑,则会在这个阶段生成对应的代理对象
Spring AOP二代(集成了AspectJ)
当Spring 2.0发布以后,Spring AOP增加了新的使用方式,Spring AOP集成了AspectJ。我们最常用的就是这个版本的Spring AOP
主要有如下变化
- 可以用POJO来定义Aspect和Adivce,并提供了一系列相应的注解,如@Aspect和@Around等。而不用像1.x版本中实现相应的接口
- 支持aspectj中的pointcut的表达方式,我们都深有体会哈
演示一下2.0版本中aop的使用方式
定义切面
@Aspect
public class AspectDefine {
@Pointcut("execution(* com.javashitang.proxy.EchoService.echo(..))")
public void pointcutName() {}
@Around("pointcutName()")
public Object calCost(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long cost = System.currentTimeMillis() - startTime;
System.out.println("cost " + cost);
return result;
}
@Before("pointcutName()")
public void beforeMethod() {
System.out.println("beforeMethod");
}
}
增加配置,注入实现类
@EnableAspectJAutoProxy
public class AspectJConfig {
@Bean
public EchoService echoService() {
return new DefaultEchoService();
}
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AspectJConfig.class, AspectDefine.class);
EchoService echoService = context.getBean(EchoService.class);
// beforeMethod
// cost 0
// hello world
System.out.println(echoService.echo("hello world"));
context.close();
}
「虽然spring2.0之后spring aop集成了AspectJ,但实际上只是拿AspectJ的“皮大衣“用了一下,因为底层的实现和织入方式还是1.x原先的实现体系」
文章转自公众号:Java识堂