Spring AOP源码分析(生成代理对象)

来源:互联网 发布:公司软件著作权转让 编辑:程序博客网 时间:2024/05/22 09:00

AOP基本概述

Advice(通知)

BeforeAdvice

package org.springframework.aop;import java.lang.reflect.Method;public interface MethodBeforeAdvice extends BeforeAdvice {    void before(Method method, Object[] args, Object target) throws Throwable;}

before是回调方法,在Advice中配置了目标方法后,会在调用目标方法时被回调。

参数:
method:目标方法
args:目标方法的输入参数
target:目标对象

AfterReturningAdvice

package org.springframework.aop;import java.lang.reflect.Method;public interface AfterReturningAdvice extends AfterAdvice {    void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;}

在目标方法调用结束并正常返回时,接口被回调

ThrowsAdvice

public interface ThrowsAdvice extends AfterAdvice {}

抛出异常时被回调,AOP使用反射实现(方法名叫AfterThrowing?)

PointCut(切入点)

public interface Pointcut {    ClassFilter getClassFilter();    MethodMatcher getMethodMatcher();    Pointcut TRUE = TruePointcut.INSTANCE;}

这里写图片描述

PointCut是通过MethodMatcher 进行切入点方法匹配的,判断是否需要对当前方法进行增强处理。

通过JdkRegexpMethodPointcut理解MethodMatcher:
在JdkRegexpMethodPointcut的基类StaticMethodMatcherPointcut中设置MethodMatcher为StaticMethodMatcherPointcut(StaticMethodMatcher)

public abstract class StaticMethodMatcherPointcut extends StaticMethodMatcher implements Pointcut {    @Override    public final MethodMatcher getMethodMatcher() {        return this;    }}

在JdkRegexpMethodPointcut中通过正则表达式匹配需要增强的方法:

protected boolean matches(String pattern, int patternIndex) {    Matcher matcher = this.compiledPatterns[patternIndex].matcher(pattern);    return matcher.matches();}

在NameMatchMethodPointcut中通过方法名进行方法的匹配:

@Overridepublic boolean matches(Method method, Class<?> targetClass) {    for (String mappedName : this.mappedNames) {        if (mappedName.equals(method.getName()) || isMatch(method.getName(), mappedName)) {            return true;        }    }    return false;}protected boolean isMatch(String methodName, String mappedName) {    return PatternMatchUtils.simpleMatch(mappedName, methodName);}

Advisor(通知器)

通知器负责把切入点和增强处理接合起来。
在切点处决定使用哪个通知

AOP设计与实现

JVM动态代理

JDK和CGLIB都是用动态代理实现的

AopProxy代理对象

Spring中,是通过ProxyFactoryBean来完成代理对象的生成的

这里写图片描述

ProxyConfig

数据基类,为ProxyFactoryBean这样的子类提供配置属性。

AdvisedSupport

AOP对通知和通知器的操作,对不同的AOP代理的生成都是一样的。对于具体生代理类,由AdvisedSupport的子类来做。

ProxyCreatorSupport

子类创建AOP代理类的辅助

ProxyFactoryBean

IOC容器中声明式配置,生成代理类

ProxyFactory

编程式使用,生成代理类

AspectJProxyFactory

需要使用AspectJ功能的AOP应用,这个起到集成Spring和AspectJ的作用

具体AOP代理对象的生成是由ProxyFactoryBean、ProxyFactory、AspectJProxyFactory完成的。

如何配置ProxyFactory?

<bean id="testAdvisor" class="com.abc.TestAdvisor" /><!-- 通知器,实现了目标对象需要增强的切面行为,也就是通知 --><!-- 这里我理解的是被代理的bean的scope如果是prototype,那么这个代理Bean就是prototype --><bean id="testAop" class="org.springframework.aop.ProxyFactoryBean">    <property name="proxyInterfaces">        <value>com.test.AbcInterface</value>    </property>    <property name="target">        <!-- 目标对象 -->        <bean class="com.abc.TestTarget" />    </property>    <property name="interceptorNames">        <!-- 需要拦截的方法接口,通知器 -->        <list>            <value>                testAdvisor            </value>        </list>    </property></bean>

代理对象生成过程总览

以singleTon为例:
这里写图片描述

代理对象获取入口:

ProxyFactoryBean的getObject

AopProxy生成过程:
这里写图片描述

ProxyFactoryBean的getObject获取代理对象

@Overridepublic Object getObject() throws BeansException {    //初始化通知器链,为代理对象配置通知器链。    initializeAdvisorChain();    //区分SingleTon和ProtoType,生成对应的Proxy    if (isSingleton()) {        // 只有SingleTon的Bean才会一开始就初始化,ProtoType的只有在请求的时候才会初始化,代理也一样        return getSingletonInstance();    } else {        if (this.targetName == null) {            logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +                    "Enable prototype proxies by setting the 'targetName' property.");        }        return newPrototypeInstance();    }}

关于initializeAdvisorChain

ProxyFactoryBean的initializeAdvisorChain

这个初始化过程有一个标志位advisorChainInitialized,这个标志用来表示通知器链是否已经初始化。

这个就是通知器链,在AdvisorSupport中:

private List<Advisor> advisors = new LinkedList<Advisor>();

如果已经初始化,那么这里不会再初始化,直接返回。初始化只是在应用第一次通过ProxyFactoryBean获取代理对象的时候。

完成这个初始化之后,接着会读取配置中出现的所有通知器(把通知器的名字交给容器的getBean,IOC容器的回调获取通知器),把通知器加入拦截器链(addAdvisoronChainCreation实现)。

private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {    if (this.advisorChainInitialized) {        return;    }    if (!ObjectUtils.isEmpty(this.interceptorNames)) {        if (this.beanFactory == null) {            throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +                    "- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));        }        // Globals can't be last unless we specified a targetSource using the property...        if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&                this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {            throw new AopConfigException("Target required after globals");        }        // Materialize interceptor chain from bean names.        for (String name : this.interceptorNames) {            if (logger.isTraceEnabled()) {                logger.trace("Configuring advisor or advice '" + name + "'");            }            if (name.endsWith(GLOBAL_SUFFIX)) {                if (!(this.beanFactory instanceof ListableBeanFactory)) {                    throw new AopConfigException(                            "Can only use global advisors or interceptors with a ListableBeanFactory");                }                addGlobalAdvisor((ListableBeanFactory) this.beanFactory,                        name.substring(0, name.length() - GLOBAL_SUFFIX.length()));            }            else {                // If we get here, we need to add a named interceptor.                // We must check if it's a singleton or prototype.                Object advice;                if (this.singleton || this.beanFactory.isSingleton(name)) {                    // Add the real Advisor/Advice to the chain.                    advice = this.beanFactory.getBean(name);                }                else {                    // It's a prototype Advice or Advisor: replace with a prototype.                    // Avoid unnecessary creation of prototype bean just for advisor chain initialization.                    advice = new PrototypePlaceholderAdvisor(name);                }                addAdvisorOnChainCreation(advice, name);            }        }    }    this.advisorChainInitialized = true;}

生成单件代理对象

ProxyFactoryBean的getSingletonInstance
private synchronized Object getSingletonInstance() {    if (this.singletonInstance == null) {        //这里会调用getBean,获取被代理对象        this.targetSource = freshTargetSource();        if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {            // 根据 AOP 框架判断需要代理的接口             Class<?> targetClass = getTargetClass();            if (targetClass == null) {                throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");            }            //这里是设置代理对象的接口            setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));        }        // Initialize the shared singleton instance.        super.setFrozen(this.freezeProxy);        //这里方法会使用ProxyFactory生成需要的Proxy        this.singletonInstance = getProxy(createAopProxy());    }    return this.singletonInstance;}//通过createAopProxy返回的AopProxy来得到代理对象protected Object getProxy(AopProxy aopProxy) {    return aopProxy.getProxy(this.proxyClassLoader);}
ProxyFactoryBean的freshTargetSource
private TargetSource freshTargetSource() {    if (this.targetName == null) {        if (logger.isTraceEnabled()) {            logger.trace("Not refreshing target: Bean name not specified in 'interceptorNames'.");        }        return this.targetSource;    }    else {        if (this.beanFactory == null) {            throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +                    "- cannot resolve target with name '" + this.targetName + "'");        }        if (logger.isDebugEnabled()) {            logger.debug("Refreshing target with name '" + this.targetName + "'");        }        Object target = this.beanFactory.getBean(this.targetName);        return (target instanceof TargetSource ? (TargetSource) target : new SingletonTargetSource(target));    }}

具体代理对象的生成,是在ProxyFactoryBean的基类AdvisedSupport的实现中借助AopProxyFactory完成。

在ProxyCreatorSupport中,AopProxy是通过AopProxyFactory生成的,需要生成的代理对象信息封装在AdvisedSupport中,这个对象也是createAopProxy的输入参数(this):

ProxyCreatorSupport的createAopProxy
protected final synchronized AopProxy createAopProxy() {    if (!this.active) {        activate();    }    //通过AopProxyFactory取得AopProxy,AopProxyFactory是在初始化函数中定义的,使用的是DefaultAopProxyFactory    return getAopProxyFactory().createAopProxy(this);}

现在问题转换为DefaultAopProxyFactory如何生成AopProxy了,这里有两种方式,JdkDynamicAopProxy和CglibProxyFactory

DefaultAopProxyFactory的createAopProxy

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {    @Override    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {            //获取配置的目标对象            Class<?> targetClass = config.getTargetClass();            if (targetClass == null) {            //如果没有目标对象,抛出异常,提醒AOP应用提供正确的目标配置                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);            }            //由于CGLIB是一个第三方类库,所以需要在CLASSPATH中配置            return new ObjenesisCglibAopProxy(config);        }        else {            return new JdkDynamicAopProxy(config);        }    }}
JdkDynamicAopProxy 生成AopProxy代理对象:
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {    @Override    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);        //JdkDynamicAopProxy 需要实现InvocationHandler这里才能传this        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {    //...代理的回调方法,invoke    //也可以理解为拦截方法    }}
CglibAopProxy生成AopProxy代理对象:
@Overridepublic 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 (Exception ex) {        // TargetSource.getTarget() failed        throw new AopConfigException("Unexpected AOP exception", ex);    }}

拦截方法写在内部类里了(在上面getCallbacks涉及到):

private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {    private final AdvisedSupport advised;    public DynamicAdvisedInterceptor(AdvisedSupport advised) {        this.advised = advised;    }    @Override    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {        Object oldProxy = null;        boolean setProxyContext = false;        Class<?> targetClass = null;        Object target = null;        try {            if (this.advised.exposeProxy) {                // Make invocation available if necessary.                oldProxy = AopContext.setCurrentProxy(proxy);                setProxyContext = true;            }            // May be null. Get as late as possible to minimize the time we            // "own" the target, in case it comes from a pool...            target = getTarget();            if (target != null) {                targetClass = target.getClass();            }            // 从advised中取得配置好的通知            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);            Object retVal;            // Check whether we only have one InvokerInterceptor: that is,            // no real advice, but just reflective invocation of the target.            // 如果没有AOP通知配置,那么直接调用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.                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);                retVal = methodProxy.invoke(target, argsToUse);            }            else {                // We need to create a method invocation...                // 通过CglibMethodInvocation来启动通知                retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();            }            retVal = processReturnType(proxy, target, method, retVal);            return retVal;        }        finally {            if (target != null) {                releaseTarget(target);            }            if (setProxyContext) {                // Restore old proxy.                AopContext.setCurrentProxy(oldProxy);            }        }    }    @Override    public boolean equals(Object other) {        return (this == other ||                (other instanceof DynamicAdvisedInterceptor &&                        this.advised.equals(((DynamicAdvisedInterceptor) other).advised)));    }    /**     * CGLIB uses this to drive proxy creation.     */    @Override    public int hashCode() {        return this.advised.hashCode();    }    protected Object getTarget() throws Exception {        return this.advised.getTargetSource().getTarget();    }    protected void releaseTarget(Object target) throws Exception {        this.advised.getTargetSource().releaseTarget(target);    }}

可以把AOP的实现部分堪称有基础设施准备和AOP运行辅助这两部分组成。

这里的AOPProxy代理对象的生成,可以看作是一个静态的AOP基础设施的建立过程。通过这个准备过程,把代理对象、拦截器这些待调用的部分都准备好,等待着AOP运行过程中对这些基础设施的使用。

对于应用触发的AOP应用,会涉及AOP框架的运行和对AOP基础设施的使用。

这些动态的运行部分,是从拦截器回调入口开始的。

0 0
原创粉丝点击