2w字搞懂Spring AOP的前世今生(三)

hexiaox810
发布于 2022-6-2 16:38
浏览
0收藏

 

Spring AOP自动动态代理的实现方式
如果让你实现对象的自动代理,你会怎么做呢?

当然是通过BeanPostProcessor来干预Bean的声明周期,聪明!Spring就是这么干的,来验证一下我们的想法

2w字搞懂Spring AOP的前世今生(三)-鸿蒙开发者社区

看这个类的继承关系,基本上就验证了我们的想法了。我们只要看看他重写了BeanPostProcessor的哪些方法即可?

「AbstractAutoProxyCreator重写了如下2个重要的方法」

postProcessBeforeInstantiation(Bean实例化前阶段执行)

postProcessAfterInitialization(Bean初始化后阶段执行)

 2w字搞懂Spring AOP的前世今生(三)-鸿蒙开发者社区
「postProcessBeforeInstantiation(Bean实例化前阶段执行)」

2w字搞懂Spring AOP的前世今生(三)-鸿蒙开发者社区

当用户自定义了TargetSource的实现时,会从TargetSource中获取目标对象生成代理。但是一般情况下我们很少会自定义TargetSource的实现。所以这部分就不再分析了。直接看postProcessAfterInitialization

「postProcessAfterInitialization(Bean初始化后阶段执行)」

2w字搞懂Spring AOP的前世今生(三)-鸿蒙开发者社区

如果没有经过代理的化就会进入wrapIfNecessary方法

2w字搞懂Spring AOP的前世今生(三)-鸿蒙开发者社区

思路很简单,就是根据Bean获取对应的Advisor,然后创建其代理对象,并返回。

2w字搞懂Spring AOP的前世今生(三)-鸿蒙开发者社区

「所以当面试官问你Spring AOP和IOC是如何结合在一起的时候,你是不是知道该如何回答了?」

在Bean生命周期的Bean初始化后阶段,如果这个Bean需要增加横切逻辑,则会在这个阶段生成对应的代理对象

Spring AOP二代(集成了AspectJ)
当Spring 2.0发布以后,Spring AOP增加了新的使用方式,Spring AOP集成了AspectJ。我们最常用的就是这个版本的Spring AOP

主要有如下变化

  1. 可以用POJO来定义Aspect和Adivce,并提供了一系列相应的注解,如@Aspect和@Around等。而不用像1.x版本中实现相应的接口
  2. 支持aspectj中的pointcut的表达方式,我们都深有体会哈
     2w字搞懂Spring AOP的前世今生(三)-鸿蒙开发者社区
    演示一下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识堂

分类
标签
已于2022-6-2 16:38:32修改
收藏
回复
举报
回复
    相关推荐