Spring AOP源码解析:二:代理对象的创建
Spring AOP源码解析:二:代理对象的创建
一、代理的类型
众所周知,Spring AOP代理的方式有2种,JDK的动态代理和Cglib的代理,前者必须实现接口,后者可以通过继承的方式实现。
二、AOP抽象
先看一段代码,AbstractAutoProxyCreator类,createProxy方法
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 通过ProxyFactory来创建代理对象。
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 要设置增强
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
从上面代码我们看到了ProxyFactory这个类是创建代理对象的核心。
首先看Advised接口,官方文档说明,存储了一些关于AOP代理工厂的一些配置,包括拦截器和增强代理接口等等。
- Interface to be implemented by classes that hold the configuration
- of a factory of AOP proxies. This configuration includes the
- Interceptors and other advice, Advisors, and the proxied interfaces.
然后看看ProxyFactory的功能,就是生成一个代理对象。然后看ProxyFactory
的父类ProxyCreatorSupport,这里有一个属性AopProxyFactory,这里AopProxyFactory负责生成AopProxy类。然后AopProxy类生成代理对象。
然后看到AdvisedSupport有一个AdvisorChainFactory,这个是用来生成代理的拦截器的,可以想到,我们生成的代理对象中可以会依赖这个。然后还保存了所有的增强Advisors。它的实现类InstantiationModelAwarePointcutAdvisorImpl,类图如下。
先看一下AopProxyFactory的默认实现DefaultAopProxyFactory,
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//根据配置来看是否使用JDK动态代理还是cglib代理。这里有两个配置项,config.isProxyTargetClass默认配置在AopAutoConfiguration类里。
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() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
下面来看一下JdkDynamicAopProxy
拦截方法的调用旧在invoke方法中,核心代码在
// Get the interception chain for this method.
// 根据AdvisedSupport来获取方法的拦截器和Advice,这里最终定位到AdvisorChainFactory接口的DefaultAdvisorChainFactory类的getInterceptorsAndDynamicInterceptionAdvice方法中。
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
// 封装成一个ReflectiveMethodInvocation对象,然后执行
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
根据AdvisedSupport来获取方法的拦截器和Advice,这里最终定位到AdvisorChainFactory接口的DefaultAdvisorChainFactory类的getInterceptorsAndDynamicInterceptionAdvice方法中。这里根据advisor获取到了Pointcut,它记录了切点的属性,匹配成功后会调用 MethodInterceptor[] interceptors = registry.getInterceptors(advisor);来获取方法拦截器。这里的拦截器就是我们上一篇讲到的AspectJAroundAdvice这种Advice。一个@Around注解对应的一个方法就是一个拦截器。然后把所有的MethodInterceptor封装成一个ReflectiveMethodInvocation,进行调用。ReflectiveMethodInvocation类中会采用责任链的方式来调用chain中的MethodInterceptor.
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
// 这里advisor的一个实现类是InstantiationModelAwarePointcutAdvisorImpl
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 这里获取了Pointcut,一个实现类是AspectJExpressionPointcut
if (config.isPreFiltered() ||
pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
if (match) {
// 如果匹配成功
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
Advice的继承图如下。
封装成ReflectiveMethodInvocation,然后调用,这里目前看起来有点问题,如果一个方法有多个拦截器的话
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
//匹配成功的话调用拦截器,这里把自己作为参数传进去,我猜测,如果后面还有其他拦截器的话,肯定会再次调用到this.proceed()
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
小结:
代理对象的创建以及代理对象的方法执行流程参与者一共有:
Advised:实现类:ProxyFactory: 记录了创建AOP代理对象的配置信息,负责创建代理对象,其内部主要逻辑是ProxyCreatorSupport类。
AopProxyFactory:实现类:DefaultAopProxyFactory负责创建可以生成代理具体的代理对象。如JdkDynamicAopProxy。
AopProxy:实现类:JdkDynamicAopProxy:生成的代理对象中存储了AdvisedSupport,AdvisedSupport中存储了所有的Advisor,Advisor中可以获取Pointcut,经过一系列匹配成功后可以获取拦截器方法,这些拦截器就是之前根据不同注解解析出来的一些类似AspectJAroundAdvice这种的Advice。