经过上篇的长篇大论分析Spring AOP原理 收集切面和实例化增强器_Alan CGH的博客-CSDN博客,我们知道了Spring是如何收集切面类并把其中的增强方法封装成增强器的。然后筛选出适用于bean的增强器数组返回。其实上一篇写的太过细节了,本篇不会再深入细节,重点放在逻辑流程上。
整个AOP代理对象的工作入口发生于AbstractAutoProxyCreator类,它同时是InstantiationAwareBeanPostProcessor,在bean的加载过程中的bean实例化前,resolveBeforeInstantion()逻辑中触发AutoProxyCreator的后置处理。所以线程会执行到这里来。在对bean收集到可适用的增强器后就是创建代理对象的工作。
1. AutoProxyCreator.getAdvicesAndAdvisorsForBean() 之后,创建代理对象
protected ob<x>ject wrapIfNecessary(ob<x>ject bean String beanName ob<x>ject cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass() beanName)) {
this.advisedBeans.put(cacheKey Boolean.FALSE);
return bean;
}
// 拿到一堆适用于bean的增强器,这回跑不掉了,要创建代理对象返回。
ob<x>ject[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass() beanName null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey Boolean.TRUE);
// 1.1 根据用户配置选择合适的代理策略
ob<x>ject proxy = createProxy(
bean.getClass() beanName specificInterceptors new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey Boolean.FALSE);
return bean;
}
1.1 将增强器转成统一的Advisor接口。初始化ProxyFactory对象,用它选择代理策略创建代理。
protected ob<x>ject createProxy(Class<?> beanClass @Nullable String beanName
@Nullable ob<x>ject[] specificInterceptors TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory beanName beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass proxyFactory);
}
}
// AOP的增强器实现对象各有不同,需要统一转成Advisor接口,为了方便叙述还是称其为增强器
Advisor[] advisors = buildAdvisors(beanName specificInterceptors);
// 给代理工厂传入增强器
proxyFactory.addAdvisors(advisors);
// 给代理工厂指定要代理的目标对象
proxyFactory.setTargetSource(targetSource);
// 模板方法设计模式运用,留给子类自定义代理工厂的机会
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 1.2 创建代理
return proxyFactory.getProxy(getProxyClassLoader());
}
public ob<x>ject getProxy(@Nullable ClassLoader classLoader) {
// 1.3 createAopProxy() 选择代理模式
// 1.4 getProxy() 创建代理对象
return createAopProxy().getProxy(classLoader);
}
1.3 选择代理模式,CGLIB代理还是JDK代理。在用户配置文件中的proxyTargetClass属性在此生效,proxy-target-class是指是否直接代理目标对象的Class对象,proxy-target-class=true时会优先选择CGLIB生成子类直接继承目标类Class对象。除非目标类本身是final或目标类是接口或已经是代理对象。
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!IN_NATIVE_IMAGE &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
// 要代理的目标对象的Class对象
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);
}
}
1.4 getProxy() 创建代理对象。根据上一步知道创建代理对象有2条分支
CGLIB创建代理
创建完毕代理对象后,那么CGLIB代理对象怎么调用目标对象的目标方法呢?
CGLIB的关键是MethodInterceptor,给代理对象注入callback[]时,将适用于代理对象的advised增强器配置对象封装成DynamicAdvisedInterceptor对象,它实现了MethodInterceptor接口。让后将DynamicAdvisedInterceptor加入callback[]。调用代理对象的方法时,所有方法被转发到拦截器链的intercept()方法。advised变量就是AdvisedSupport类是AOP配置对象,里面封装有适用bean的增强器链。
@Override
@Nullable
public ob<x>ject intercept(ob<x>ject proxy Method method ob<x>ject[] args MethodProxy methodProxy) throws Throwable {
ob<x>ject oldProxy = null;
boolean setProxyContext = false;
ob<x>ject target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
// expose-proxy属性生效。原理是每次方法执行时将代理对象放入线程的LocalMap中。每次拦截器和方法执行完毕再移除
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 将增强器做成链
List<ob<x>ject> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method targetClass);
ob<x>ject retVal;
// Check whether we only have one InvokerInterceptor: that is
// no real advice but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// 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.
ob<x>ject[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method args);
retVal = methodProxy.invoke(target argsToUse);
}
else {
// 增强器链非空。创建ReflectiveMethodInvocation对象执行增强器链。该方法的增强方法都会在这里执行
retVal = new CglibMethodInvocation(proxy target method args targetClass chain methodProxy).proceed();
}
retVal = processReturnType(proxy target method retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
最后来看看JDK代理对象
Spring创建的JdkDynamicAopProxy是直接实现了InvocationHandler接口。handler是链接代理对象和目标对象的中间桥梁。代理对象所有方法调用被转发到invoke(),所以在invoke()中实现了增强器的执行和目标方法的执行。
所有代理对象的被增强过的方法调用时,都会先来到这里
@Override
@Nullable
public ob<x>ject invoke(ob<x>ject proxy Method method ob<x>ject[] args) throws Throwable {
ob<x>ject oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
ob<x>ject target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(ob<x>ject) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised method args);
ob<x>ject retVal;
if (this.advised.exposeProxy) {
// expose proxy生效
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 拿到方法的增强器链
List<ob<x>ject> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method targetClass);
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.
ob<x>ject[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method args);
retVal = AopUtils.invokeJoinpointUsingReflection(target method argsToUse);
}
else {
// 创建增强器链,链式执行。各增强器自己维护和目标方法的顺序,即是先执行增强方法还是先执行目标方法。
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy target method args targetClass chain);
retVal = invocation.proceed();
}
// 省略代码..
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}