Spring源码阅读(七)—AOP创建代理
本文主要分析了AOP功能实现中的代理的具体创建过程
Spring AOP主要提供了两种代理模式JDK动态代理和CGLIB动态代理
个人主页:tuzhenyu’s page
原文地址: Spring源码阅读(七)—AOP创建代理
(1) Spring AOP创建代理的入口
- 在获取增强列表后,调用createProxy()方法作为创建代理的入口,在createProxy()方法中Spring将创建代理委托给ProxyFactory进行处理,在createProxy()方法中对ProxyFactory进行初始化操作
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if(!proxyFactory.isProxyTargetClass()) {
if(this.shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
this.evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
Advisor[] var7 = advisors;
int var8 = advisors.length;
for(int var9 = 0; var9 < var8; ++var9) {
Advisor advisor = var7[var9];
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
this.customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if(this.advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(this.getProxyClassLoader());
}
- 完成ProxyFactory配置后调用getProxy()方法创建代理
public Object getProxy(ClassLoader classLoader) {
return this.createAopProxy().getProxy(classLoader);
}
-
在getProxy()方法中会调用createAopProxy()方法区分用哪种代理模式创建代理
对接口生成代理使用JDK动态代理模式
对类生成代理使用CGLIB动态代理模式
可以通过配置文件指定对接口使用CGLIB生成代理
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);
}
if (!cglibAvailable) {
throw new AopConfigException(
"Cannot proxy target class because CGLIB2 is not available. " +
"Add CGLIB to the class path or specify proxy interfaces.");
}
return CglibProxyFactory.createCglibProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
(2) Spring AOP的JDK动态代理创建
- 创建JdkDynamicAopProxy类实现InvocationHandler接口,作为代理的Handler类,包含getProxy()方法,invoke()方法等.
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if(config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
} else {
this.advised = config;
}
}
- 通过getProxy()方法创建代理,并调用Proxy.newProxyInstance()方法将JdkDynamicAopProxy类作为Handler传入
public Object getProxy(ClassLoader classLoader) {
if(logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
- JDK动态代理逻辑的实现在Handler的invoke()方法中,在invoke()方法中将增强转换成拦截器链,并调用proceed()方法顺序执行,进而实现代理类的执行逻辑.
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class targetClass = null;
Object target = null;
Object retVal;
try {
if(!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
Boolean retVal2 = Boolean.valueOf(this.equals(args[0]));
return retVal2;
}
if(!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
Integer retVal1 = Integer.valueOf(this.hashCode());
return retVal1;
}
if(this.advised.opaque || !method.getDeclaringClass().isInterface() || !method.getDeclaringClass().isAssignableFrom(Advised.class)) {
if(this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
if(target != null) {
targetClass = target.getClass();
}
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if(chain.isEmpty()) {
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
} else {
ReflectiveMethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
Class returnType = method.getReturnType();
if(retVal != null && retVal == target && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
} else if(retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
}
Object var13 = retVal;
return var13;
}
retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
} finally {
if(target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if(setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
return retVal;
}
(3) Spring AOP的CGLIB动态代理创建
- 创建CglibAopProxy类,在此类中包含代理类创建的入口getProxy()
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if(config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
} else {
this.advised = config;
this.advisedDispatcher = new CglibAopProxy.AdvisedDispatcher(this.advised);
}
}
- getProxy()方法中实现了Enhancer类对象的创建,并将一系列的增强封装在Callback类中,装载进Enhancer对象中.由Enhancer对象创建代理类.
public Object getProxy(ClassLoader classLoader) {
if(logger.isDebugEnabled()) {
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
}
try {
Class ex = this.advised.getTargetClass();
Assert.state(ex != null, "Target class must be available for creating a CGLIB proxy");
Class proxySuperClass = ex;
int x;
if(ClassUtils.isCglibProxyClass(ex)) {
proxySuperClass = ex.getSuperclass();
Class[] enhancer = ex.getInterfaces();
Class[] callbacks = enhancer;
int types = enhancer.length;
for(x = 0; x < types; ++x) {
Class additionalInterface = callbacks[x];
this.advised.addInterface(additionalInterface);
}
}
this.validateClassIfNecessary(proxySuperClass, classLoader);
Enhancer var12 = this.createEnhancer();
if(classLoader != null) {
var12.setClassLoader(classLoader);
if(classLoader instanceof SmartClassLoader && ((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass)) {
var12.setUseCache(false);
}
}
var12.setSuperclass(proxySuperClass);
var12.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
var12.setNamingPolicy(SpringNamingPolicy.INSTANCE);
var12.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
Callback[] var13 = this.getCallbacks(ex);
Class[] var14 = new Class[var13.length];
for(x = 0; x < var14.length; ++x) {
var14[x] = var13[x].getClass();
}
var12.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
var12.setCallbackTypes(var14);
return this.createProxyClassAndInstance(var12, var13);
} catch (CodeGenerationException var9) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" + this.advised.getTargetClass() + "]: " + "Common causes of this problem include using a final class or a non-visible class", var9);
} catch (IllegalArgumentException var10) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" + this.advised.getTargetClass() + "]: " + "Common causes of this problem include using a final class or a non-visible class", var10);
} catch (Exception var11) {
throw new AopConfigException("Unexpected AOP exception", var11);
}
}
(3) 总结
Spring AOP代理创建主要是将获取的增强与委托类组合生成代理类,主要是通过两种代理模式实现JDK动态代理和CGLIB动态代理.JDK动态代理是将传入的增强封装成代理链放入invoke()方法中,通过Proxy.newProxyInstance()方法将生成代理类.而CGLIB动态代理是将传入的增强封装成代理连放入Callback中,最后传给Enhancer中通过该类的create()方法产生代理类.