Spring AOP源码脉络分析
客户端通过getBean获取bean,实际是调用了
AbstractApplicationContext.getBean(String name)
AbstractApplicationContextImpl.getBeanFactory().getBean(name)
AbstractBeanFactory.doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
AbstractBeanFactory.getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd)
FactoryBeanRegistrySupport.getCachedObjectForFactoryBean(String beanName)
最终是从一个factoryBeanObjectCache
的ConcurrentHashMap
获取Bean
。从这点上,必定会有一个地方将创建的bean
通过Map.put
到factoryBeanObjectCache
通过AbstractBeanFactory.getObjectForBeanInstance
方法可知:
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
首次加载的时候,会调用AbstractBeanFactory.getObjectFromFactoryBean(factory, beanName, !synthetic)
这里的重点逻辑:
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
postProcessObjectFromFactoryBean
实际调用了AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(object, beanName)
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
这段代码拿到AbstractAdvisingBeanPostProcessor
并调用postProcessAfterInitialization
,在postProcessAfterInitialization
中调用了ProxyFactory.getProxy(ClassLoader classLoader)
return proxyFactory.getProxy(getProxyClassLoader());
proxyFactory.createAopProxy
方法中获取DefaultAopProxyFactory
并调用createAopProxy
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException();
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
其中:
-
config.isOptimize()
:是否对生产代理策略使用优化true
:进行优化,如果有接口就代理接口(使用JDK动态代理),没有接口代理类(CGLIB代理);false
:不进行优化(默认值是false)
-
config.isProxyTargetClass()
:是否强制使用CGLIB来实现代理-
true
: 强制使用CGLIB来实现代理 -
false
:不强制使用CGLIB来实现代理,首选JDK来实现代理(默认值也是false
)
-
-
hasNoUserSuppliedProxyInterfaces(config)
:判断代理对象是否有实现接口
以上方法就是判断用哪种方式创建代理对象,
ObjenesisCglibAopProxy(继承CglibAopProxy)
JdkDynamicAopProxy
返回的AopProxy
再调用getProxy
,最终调用的是Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
Proxy底层是通过反编译代理类的产生字节码进行增强处理的
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
由于jdk的动态代理生成的新的类是默认继承自Proxy的,且JAVA不支持多继承,所谓为了能够生成代理类,只能通过实现被代理类的接口的方式来达到目的,这也是为什么JDK动态代理要求代理对象是基于接口的原因.
附:
- 简化了的时序图
- 阅读源码的几个技巧
- 条件断点:通过对断点设置条件(一般的IDE都支持)来精准拦截预设值
- 聚焦主题:只关注我们关心的源码,对其他不影响的方法不去关注,但要知道方法的作用
- 对于关注的对象的运行结果,明确结果是否存在后,放过对于相反(即不存在情况下)的代码逻辑的阅读与分析
- 对于不知道后续的运行结果如何,避免重新跑一遍程序,可通过IDE提供的evaluate expresssion来即时计算表达式的值
一句话总结AOP原理: 通过反编译被代理对象产生的字节码,结合JVM指令生成新的代理对象