深挖Spring Aop 底层实现(一)

本文可任意转载,转载时请保留作者 Zevi@掘金署名及文章出处juejin.im/post/5b9357…

前言

Spring Aop 底层是由Java 动态代理和 cglib 实现的,但是我们会有一些问题:

  • Spring Aop默认使用哪种技术实现Aop?
  • 什么情况下使用Java动态代理?什么情况下使用cglib呢?
好的,我们现在就带着这2个问题开始在Spring 源码里寻找答案。

开始

准备

首先我们写个简单的Spring Aop的环境

依赖的包:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.8.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.0</version>
</dependency>
复制代码

Spring配置类 AppConfig:

@Configuration
@ComponentScan(basePackages = "com.dahafo")
@EnableAspectJAutoProxy
public class AppConfig {

}
复制代码

Aop处理类:

@Aspect
@Component
public class AppAspect {

    //定义一个切点
    @Pointcut("execution(* com.dahafo.dao..*.*(..))")
    public void pointCut(){

    }

    @After("pointCut()")
    public void after(){
        System.out.println("aspect---after---");
    }
    
}
复制代码

dao层接口

public interface Dao {

    public void save();
}
复制代码

当然需要一个dao 层的方法,HelloDao:

@Component
public class HelloDao implements Dao{

    public void save() {
        System.out.println("dao---save---");
    }
}
复制代码

好了,准备代码差不多了,我们再写一个main方法启动,

public class Test {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context= new AnnotationConfigApplicationContext(AppConfig.class);
        context.start();
        Dao dao=context.getBean(Dao.class);
        dao.save();
    }
}
复制代码

先看下效果,控制台成功打印

dao---save---
aspect---after---
复制代码

说明我们写的aop 能运行成功

开始调试

打断点在Dao dao=context.getBean(Dao.class)上,Debug启动,进入getBean(Dao.class)方法,走到AbstractApplicationContext#getBean(java.lang.Class<T>)方法的return getBeanFactory().getBean(requiredType),进入这段代码执行。
第一个进入的是getBeanFactory()方法,直接走完,回到return getBeanFactory().getBean(requiredType) ,再次进入,再进入DefaultListableBeanFactory#getBean(java.lang.Class<T>, java.lang.Object...)方法。
进入这段代码NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);,走到return new NamedBeanHolder<>(beanName, getBean(beanName, requiredType, args)),再进入,再进入到AbstractBeanFactory#doGetBean方法,走到Object sharedInstance = getSingleton(beanName)这一行,进入,再进入。
到了DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)方法,我们看第一行Object singletonObject = this.singletonObjects.get(beanName)this.singletonObjects,是一个 ConcurrentHashMap,它里面保存了很多类,我们可以从里面找到key为helloDao的类,我们往下走一步,可以看到singletonObject有值了

这个类是我们的HelloDao经过jdk动态代理生成的类,至此,我们已经可以找到spring从哪里拿到了我们代理后的类,但是,我们怎么知道这个类是怎么生成的呢?我们上面2个问题还是没有答案。

预知后事如何,请听下回分解,深挖Spring Aop 底层实现(二)待续

本文可任意转载,转载时请保留作者 Zevi@掘金署名及文章出处juejin.im/post/5b9357…

转载于:https://juejin.im/post/5b9357786fb9a05d330a9a55

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值