Spring|Spring AOP核心源码解读
上一篇 << 下一篇 >>>Spring事务常识汇总
回顾bean容器的初始化过程
1、this.refresh(); 配置初始化后执行核心源码 1、启动@EnableAspectJAutoProxy时,会往IOC容器中注入AnnotationAwareAspectJAutoProxyCreator.class
2、this.finishBeanFactoryInitialization(beanFactory); 初始化所有单例
3、beanFactory.preInstantiateSingletons(); 初始化所有非懒加载的单例对象
4、this.getBean(beanName); --doGetBean 判断是否初始化过,没初始化的话执行后面的创建动作
5、this.createBean(beanName, mbd, args); --this.doCreateBean(beanName, mbdToUse, args); 单例情况下调用此方法
6、BeanWrapper instanceWrapper = this.createBeanInstance(beanName, mbd, args); 创建bean转换为wrapper方法
7、this.populateBean(beanName, mbd, instanceWrapper); 设置属性
8、exposedObject = this.initializeBean(beanName, exposedObject, mbd); 执行初始化方法
9、this.invokeAwareMethods(beanName, bean); 检查aware依赖
10、wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName); bean前置加强
11、 this.invokeInitMethods(beanName, wrappedBean, mbd); 执行init方法
12、wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 后置加强
13、bean正常使用
14、bean销毁
@EnableAspectJAutoProxy
@Import({AspectJAutoProxyRegistrar.class})
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
beanId:org.springframework.aop.config.internalAutoProxyCreator
class:AnnotationAwareAspectJAutoProxyCreator.class
2、AnnotationAwareAspectJAutoProxyCreator.class类图 最终属于BeanPostProcessor的子类
>>>>AspectJAwareAdvisorAutoProxyCreator
>>>>>>>>AbstractAdvisorAutoProxyCreator
>>>>>>>>>>>>AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAwareSmartInstantiationAwareBeanPostProcessor.class
>>>>InstantiationAwareBeanPostProcessor extends BeanPostProcessor
3、BeanPostProcessor 拥有前置和后置通知,可看到子类AbstractAutoProxyCreator,可以看到AOP是后置代理起到了作用
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}return bean;
}
4、this.wrapIfNecessary(bean, beanName, cacheKey);
//判断是否需要增加
protected boolean isInfrastructureClass(Class> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && this.logger.isTraceEnabled()) {
this.logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}return retVal;
}
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
//需要增强的话,则创建JDK动态代理或cglib动态代理
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
proxyFactory.getProxy(this.getProxyClassLoader());
this.createAopProxy().getProxy(classLoader);
//如果请求是接口,则调用JdkDynamicAopProxy,否则调用ObjenesisCglibAopProxy
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
Class> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
} else {
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
【Spring|Spring AOP核心源码解读】推荐阅读:
<< << << << << << << <<<手动事务和自定义注解事务代码参考
<<
推荐阅读
- 由浅入深理解AOP
- Activiti(一)SpringBoot2集成Activiti6
- 期刊|期刊 | 国内核心期刊之(北大核心)
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- 2018-07-09|2018-07-09 Spring 的DBCP,c3p0
- 活跃社群的核心标准是什么()
- VueX--VUE核心插件
- spring|spring boot项目启动websocket
- Spring|Spring Boot 整合 Activiti6.0.0