Spring AOP分析(3) -- CglibAopProxy实现AOP

本文内容纲要:Spring AOP分析(3) -- CglibAopProxy实现AOP

上文探讨了应用JDK动态代理实现Spring AOP功能的方式,下面将继续探讨Spring AOP功能的另外一种实现方式 -- CGLIB。

首先,来看看类名CglibAopProxy,该类实现了两个接口:一个是AopProxy接口,一个是Serializable接口。直接忽略Serializable接口,AopProxy接口中只定义了两个同名方法getProxy。如下所示:

class CglibAopProxy implements AopProxy, Serializable

类中有一个非常重要的属性advised,该属性在JdkDynamicAopProxy中也存在,主要用于配置代理信息,是一个非常重要的属性,如下

protected final AdvisedSupport advised;

属性为final类型,可以被子类继承,一旦赋值后便不能改变。在CglibAopProxy中,advised在构造器中被赋值,后续不可更改:

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");

}

this.advised = config;

this.advisedDispatcher = new AdvisedDispatcher(this.advised);

}

跟JdkDynamicAopProxy一样,实现了AopProxy接口,实现了getProxy()方法,如下:

@Override

public Object getProxy(ClassLoader classLoader) {

if (logger.isDebugEnabled()) {

logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());

}

try {

Class<?> rootClass = this.advised.getTargetClass();

Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

Class<?> proxySuperClass = rootClass;

if (ClassUtils.isCglibProxyClass(rootClass)) {

proxySuperClass = rootClass.getSuperclass();

Class<?>[] additionalInterfaces = rootClass.getInterfaces();

for (Class<?> additionalInterface : additionalInterfaces) {

this.advised.addInterface(additionalInterface);

}

}

// Validate the class, writing log messages as necessary.

validateClassIfNecessary(proxySuperClass, classLoader);

// Configure CGLIB Enhancer...

Enhancer enhancer = createEnhancer();

if (classLoader != null) {

enhancer.setClassLoader(classLoader);

if (classLoader instanceof SmartClassLoader &&

((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {

enhancer.setUseCache(false);

}

}

enhancer.setSuperclass(proxySuperClass);

enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));

enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);

enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

Callback[] callbacks = getCallbacks(rootClass);

Class<?>[] types = new Class<?>[callbacks.length];

for (int x = 0; x < types.length; x++) {

types[x] = callbacks[x].getClass();

}

// fixedInterceptorMap only populated at this point, after getCallbacks call above

enhancer.setCallbackFilter(new ProxyCallbackFilter(

this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));

enhancer.setCallbackTypes(types);

// Generate the proxy class and create a proxy instance.

return createProxyClassAndInstance(enhancer, callbacks);

}

catch (CodeGenerationException ex) {

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",

ex);

}

catch (IllegalArgumentException ex) {

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",

ex);

}

catch (Throwable ex) {

// TargetSource.getTarget() failed

throw new AopConfigException("Unexpected AOP exception", ex);

}

}

在创建代理过程中需要判断被代理类是否已经进行过验证,若没有验证过则执行验证。验证方法如下:

private void doValidateClass(Class<?> proxySuperClass, ClassLoader proxyClassLoader, Set<Class<?>> ifcs) {

if (proxySuperClass != Object.class) {

Method[] methods = proxySuperClass.getDeclaredMethods();

for (Method method : methods) {

int mod = method.getModifiers();

if (!Modifier.isStatic(mod)) {

if (Modifier.isFinal(mod)) {

if (implementsInterface(method, ifcs)) {

logger.warn("Unable to proxy interface-implementing method [" + method + "] because " +

"it is marked as final: Consider using interface-based JDK proxies instead!");

}

logger.info("Final method [" + method + "] cannot get proxied via CGLIB: " +

"Calls to this method will NOT be routed to the target instance and " +

"might lead to NPEs against uninitialized fields in the proxy instance.");

}

else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) && !Modifier.isPrivate(mod) &&

proxyClassLoader != null && proxySuperClass.getClassLoader() != proxyClassLoader) {

logger.info("Method [" + method + "] is package-visible across different ClassLoaders " +

"and cannot get proxied via CGLIB: Declare this method as public or protected " +

"if you need to support invocations through the proxy.");

}

}

}

doValidateClass(proxySuperClass.getSuperclass(), proxyClassLoader, ifcs);

}

}

接着配置CGLIB加强createEnhancer(),最后创建代理类生成代理实例createProxyClassAndInstance(enhancer, callbacks)

本文内容总结:Spring AOP分析(3) -- CglibAopProxy实现AOP

原文链接:https://www.cnblogs.com/hthuang/p/7797595.html

以上是 Spring AOP分析(3) -- CglibAopProxy实现AOP 的全部内容, 来源链接: utcz.com/z/362841.html

回到顶部