[KANMARS原创] - Spring 源码解析-AOP的实现
Spring 源码解析-AOP的实现
1、spring通过自带的插件机制实现NameSpaceHandler处理xml配置
遇到<AOP:>标签,交给
AopNameSpaceHandler进行执行
2、Spring解析BeanDefinition
在AopNameSpaceHandler可以看到<aop:config>是交给org.springframework.aop.config.ConfigBeanDefinitionParser进行解析
2.1 注册自动代理类创造者
ConfigBeanDefinitionParser.configureAutoProxyCreator
在spring的BeanFactory中注册一个名称为”org.springframework.aop.config.internalAutoProxyCreator”,
类名为:AspectJAwareAdvisorAutoProxyCreator.class的BeanPostProcessors
2.2 根据不同的标签进行解析
2.2.1标签类型为<aop:pointcut>,进入parsePointcut分支
创建PointcutDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(AspectJExpressionPointcut.class);
beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
beanDefinition.setSynthetic(true);
beanDefinition.getPropertyValues().add(EXPRESSION, expression);
其中expression即为配置的切入点,例如expression=”execution(* cn.kanmars.service.impl.DubboServiceImpl.exec(..))”
之后将PointcutDefinition注册到beanFactory中
2.2.2标签类型为<aop:aspect>,进入parseAspect分支,按照Advistor进行解析,进入的方法为private AbstractBeanDefinition parseAdvice
2.2.2.1 创建method factory bean
new RootBeanDefinition(MethodLocatingFactoryBean.class);
2.2.2.2 创建instance factory definition
RootBeanDefinition aspectFactoryDef = new RootBeanDefinition(SimpleBeanFactoryAwareAspectInstanceFactory.class);
SimpleBeanFactoryAwareAspectInstanceFactory类继承自org.springframework.aop.aspectj.Ordered接口
2.2.2.3 创建 register the pointcut 此处spring的注释与代码有差异
AdviseClass ConfigBeanDefinitionParser.getAdviceClass
按照不同的类型创建advistor
其中
BEFORE AspectJMethodBeforeAdvice.class;
AFTER AspectJAfterAdvice.class;
AFTER_RETURNING_ELEMENT AspectJAfterReturningAdvice.class;
AFTER_THROWING_ELEMENT AspectJAfterThrowingAdvice.class;
AROUND AspectJAroundAdvice.class;
RootBeanDefinition adviceDefinition = new RootBeanDefinition(getAdviceClass(adviceElement, parserContext));
2.2.2.3 配置advistor configure the advisor
RootBeanDefinition advisorDefinition = new RootBeanDefinition(AspectJPointcutAdvisor.class);
2.2.2.4 创建切面组件
AspectComponentDefinition aspectComponentDefinition = createAspectComponentDefinition(aspectElement, aspectId, beanDefinitions, beanReferences, parserContext);
2.2.3标签类型为<aop:advistor>,进入parseAdvisor分支
解析AdvisorBeanDefinition
注册到beanFactory中
3、AbstractApplicationContext.registerBeanPostProcessors。注册BeanPostProcessors
3.1 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
获取到了org.springframework.aop.config.internalAutoProxyCreator
由于AspectJAwareAdvisorAutoProxyCreator实现了Order接口,因此在第二顺序注册
4、AbstractApplicationContext.finishBeanFactoryInitialization,对象实例化
4.1 获取到RootBeanDefinition
4.2 在实例化AbstractAutowireCapableBeanFactory.createBean()448行,此处由于bean为空,所以并未执行
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
”BeanPostProcessor before instantiation of bean failed”, ex);
}
对代理类进行实例化
执行AspectJAwareAdvisorAutoProxyCreator.postProcessBeforeInstantiation方法
返回为空
4.3 对对象进行实例化
4.4 初始化Bean属性Initialize the bean instance.
populateBean()
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName))
exposedObject = initializeBean(beanName, exposedObject, mbd)
4.5 执行afterInitialization方法
AspectJAwareAdvisorAutoProxyCreator.postProcessAfterInstantiation
AspectJAwareAdvisorAutoProxyCreator.parent().parent()即AbstractAutoProxyCreator.postProcessAfterInitialization
AbstractAutoProxyCreator.postProcessAfterInitialization
AbstractAutoProxyCreator.wrapIfNecessary
4.5.1 //获取所有的advistor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
4.5.2 创建代理类
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
4.5.2.1 创建一个ProxyFactory
Advised
ProxyConfig
AdvisedSupport AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();
ProxyCreatorSupport this.aopProxyFactory = new DefaultAopProxyFactory();
ProxyFactory proxyFactory = new ProxyFactory();
4.5.2.2 创建advistors buildAdvisors
从specificInterceptors中创建Advisor数组
proxyFactory.addAdvisor(advisors);//将advistors放入proxyFactory中
4.5.2.3 调用proxyFactory.getProxy
调用createAopProxy().getProxy
调用getAopProxyFactory().createAopProxy(this).getProxy
调用DefaultAopProxyFactory.createAopProxy(AdvisedSupport config).getProxy –此处传递的config,即为proxyFactory————————–>在此处进行了JDK代理和CGLIB代理的选择
4.5.2.3.1 DefaultAopProxyFactory.createAopProxy(AdvisedSupport config) –> return CglibProxyFactory.createCglibProxy(config)
4.5.2.3.2 DefaultAopProxyFactory.createAopProxy(AdvisedSupport config) –> return new CglibAopProxy(advisedSupport);
4.5.2.3.3 cglibAopProxy.this.advised = config;
cglibAopProxy.advisedDispatcher = new AdvisedDispatcher(this.advised);
即获取到AopProxy为CglibAopProxy
4.5.2.3.4 调用CglibAopProxy.getProxy(); –>
4.5.2.3.4.1 生成代理类,代码如下
Enhancer enhancer = createEnhancer()
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new MemorySafeUndeclaredThrowableStrategy(UndeclaredThrowableException.class));
enhancer.setInterceptDuringConstruction(false);
Callback[] callbacks = getCallbacks(rootClass);
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised)
Callback[] mainCallbacks = new Callback[]{
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher,
this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
enhancer.setCallbacks(callbacks);
proxy = enhancer.create();//此处即为代理对象。
此时return 一个proxy,即为所需要的代理
4.5.2.3.4.2 以上enhancer的代码可以参见CGLIB的相关文档,大意如下:
4.5.2.3.4.2.1 生成了一个Callback数组,该Callback为回调函数,用于在匹配到对应方法时执行。
4.5.2.3.5.2.2 在enhancer中有一个ProxyCallbackFilter类,该类用于“对callback数组进行匹配”
例如当运行ProxyCallbackFilter的accept方法返回0时,执行的是callback数组中的第0个回调函数(这是个很奇葩很与众不同的概念)
目前ProxyCallbackFilter返回值如下:
在CallbackFilter中配置的顺序为
private static final int AOP_PROXY = 0; 普通代理
private static final int INVOKE_TARGET = 1; invoke target without considering advice,直接执行目标的方法-在配置了pointcut,但是该对象并无通知的情况下
private static final int NO_OVERRIDE = 2; finalize对象析构方法
private static final int DISPATCH_TARGET = 3; 想请求转向到另一个目标
private static final int DISPATCH_ADVISED = 4; 目标转向
private static final int INVOKE_EQUALS = 5; 执行equal方法
private static final int INVOKE_HASHCODE = 6; 执行hashCode方法
可以看到:
a、当开始在运行时织入动态字节码时,
b、ProxyCallbackFilter中会根据:“方法名称,方法是否是析构函数,方法是否有通知等种种不同的类型”,返回0,1,2,3,4,5,6这样七个数字
c、cglib根据返回的0,1,2,3,4,5,6分别选择Callbacks中对应的回调函数,将回调函数织入字节码中。
4.6 将proxy注入singleObject单例缓存,即为最终的代理对象
以上内容,即为SpringAOP的CGLIB实现。
众所周知,SpringAOP有两种实现方式,
方式一为CGLIB,即:没有实现接口的类的代理,用CGLIB实现
方法二为JDK自带代理,即实现了某接口的类的代理,用JDK自带代理实现
代码位于DefaultAopProxyFactory
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
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.”);
}
if (targetClass.isInterface()) {
return new JdkDynamicAopProxy(config);
}
return CglibProxyFactory.createCglibProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}