调用链
先来看一段堆栈信息【以spring3.0.6为例】,接下来分析aop标签乾坤
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'b1' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.uu.T.main(T.java:9)
Caused by: org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
at org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(DefaultAopProxyFactory.java:67)
at org.springframework.aop.framework.ProxyCreatorSupport.createAopProxy(ProxyCreatorSupport.java:104)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:112)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:476)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1426)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
动态代理生成入口
动态代理生成是在spring处于对象生命周期的后期,目标对象实例化以后会逐个调用容器中定义的 BeanPostProcessor来处理对象;
其中aop的BeanPostProcessor是只要你在配置文件中引入了 类似:<aop:....> 这样的标签就会自动注册到容器中;
具体逻辑可以参考文章(我觉得写得不错):
http://www.jianshu.com/p/867991f3daa0
aop jar包中
/META-INF/spring.handlers 内容:
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
自动执行 init() 方法
标签解析入口
public void init() {
// In 2.0 XSD as well as in 2.1 XSD.
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace as of 2.1
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
其中
1、ConfigBeanDefinitionParser 会注入AspectJAwareAdvisorAutoProxyCreator类
代码追踪:
org.springframework.aop.config.ConfigBeanDefinitionParser#parse
↓
org.springframework.aop.config.ConfigBeanDefinitionParser#configureAutoProxyCreator
↓
org.springframework.aop.config.AopNamespaceUtils#registerAspectJAutoProxyCreatorIfNecessary
↓
org.springframework.aop.config.AopConfigUtils#registerAspectJAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
2、AspectJAutoProxyBeanDefinitionParser 会注入 AnnotationAwareAspectJAutoProxyCreator 类
代码追踪:
org.springframework.aop.config.AspectJAutoProxyBeanDefinitionParser#parse
↓
org.springframework.aop.config.AopNamespaceUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary
↓
org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
这些类都是BeanPostProcessor实现类,BeanPostProcessor是生命周期方法的重要部分;
AspectJAwareAdvisorAutoProxyCreator
由于是BeanPostProcessor的子类,在spring完成单例对象初始化后会自动调用
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization,即容器里所有的类初始化完成后都会到这里来进行“洗礼”;
代码跟踪:
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
↓
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
↓
//判断是否需要生成代理
org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip
↓
//这个方法会决定使用jdk动态代理或者是使用cglib
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
↓
//cglib
org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)
或者
//jdk动态代理
org.springframework.aop.framework.JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)
AnnotationAwareAspectJAutoProxyCreator
该类 extends AspectJAwareAdvisorAutoProxyCreator,所以流程差不多;区别点可以看看覆盖了哪些方法即清晰了