本文可任意转载,转载时请保留作者 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
有值了
预知后事如何,请听下回分解,深挖Spring Aop 底层实现(二)待续
本文可任意转载,转载时请保留作者 Zevi@掘金署名及文章出处juejin.im/post/5b9357…