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
if(!this.hashCodeDefined && AopUtils.isHashCodeMethod(method))
if(this.advised.opaque || !method.getDeclaringClass().isInterface() || !method.getDeclaringClass().isAssignableFrom(Advised.class))
target = targetSource.getTarget();
if(target != null)
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(
method, targetClass);
if(chain.isEmpty())
else
Class returnType =
method.getReturnType();
if(retVal != null && retVal == target && returnType.isInstance(proxy) && !RawTargetAccess.
class.isAssignableFrom(
method.getDeclaringClass())) else if(retVal == null && returnType != Void.TYPE && returnType.isPrimitive())
Object var13 = retVal;
return var13;
}
retVal = AopUtils.invokeJoinpointUsingReflection(this.advised,
method, args);
}
finally
if(setProxyContext)
}
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()方法产生代理类.