Spring源码学习之认识AOP

来源:互联网 发布:京东抢券软件安卓 编辑:程序博客网 时间:2024/06/06 01:08

前言

作为Spring的重要特性之一,AOP的作用当然是毋庸置疑的。它使我们可以在代码执行过程中,横切代码,封装那些重复执行的操作。保证代码的模块化和管理时的便捷性。而这篇博文将从源码的角度解析AOP的工作原理和使用过程:

简易的AOP流程

简单的AOP实现

<!-- bean.xml --><bean id="testadvice" class="chapter3_AOP.TestAdvice"></bean><bean id="aop" class="org.springframework.aop.framework.ProxyFactoryBean">        <!-- 可有可无 -->        <property name="proxyInterfaces">            <value>chapter3_AOP.OperateApi</value>        </property>        <property name="target">            <bean class="chapter3_AOP.OperateTarget"></bean>        </property>        <property name="interceptorNames">            <list>                <value>testadvice</value>            </list>        </property>    </bean>
// OperateTarget.java public class OperateTarget implements OperateApi{    @Override    public void update() {        System.out.println("update");    }}
// TestAdvice.javapublic class TestAdvice implements MethodBeforeAdvice{    @Override    public void before(Method method, Object[] args, Object target) throws Throwable {        System.out.println("prehandle");    }}
// client.javapublic class client {    public static void main(String []args){        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");        OperateApi api = (OperateApi)ac.getBean("aop");        api.update();    }}
// 输出prehandleupdate

AOP流程

1.生成代理对象

ProxyFactoryBean的实现是Spring IoC环境中创建AOP的底层方法,也是最灵活的方法。因此通过ProxyFactoryBean的使用,来看看AOP的运行到底是怎样的过程。

// ProxyFactoryBean.java// 获得生成的代理对象public Object getObject() throws BeansException {        initializeAdvisorChain();        if (isSingleton()) {            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();        }    }// 创建拦截器链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));            }            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");            }            // 遍历设置的拦截器            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");                    }                  // 添加所有全局拦截器,主要过程是在beanfactory找出所有advisor和interceptor,                  // 添加到advisors中                    addGlobalAdvisor((ListableBeanFactory) this.beanFactory,                            name.substring(0, name.length() - GLOBAL_SUFFIX.length()));                }                else {                    Object advice;                    if (this.singleton || this.beanFactory.isSingleton(name)) {                        // 之前分析过的从beanfactory中直接获取对象                        advice = this.beanFactory.getBean(name);                    }                    else {                        advice = new PrototypePlaceholderAdvisor(name);                    }                    addAdvisorOnChainCreation(advice, name);                }            }        }        this.advisorChainInitialized = true;    }// 添加拦截器private void addAdvisorOnChainCreation(Object next, String name) {        // 将获得的类转换成advisor。如果是advice,将advice作为参数生成一个新的advisor        Advisor advisor = namedBeanToAdvisor(next);        if (logger.isTraceEnabled()) {            logger.trace("Adding advisor with name '" + name + "'");        }        addAdvisor(advisor);    }// 获取单例实例private synchronized Object getSingletonInstance() {        if (this.singletonInstance == null) {            // 根据设置的targetName获取实例并包裹在targetSource中            this.targetSource = freshTargetSource();            if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {                // 获得Class                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);            // 生成代理实例的关键            this.singletonInstance = getProxy(createAopProxy());        }        return this.singletonInstance;    }private synchronized Object newPrototypeInstance() {        // In the case of a prototype, we need to give the proxy        // an independent instance of the configuration.        // In this case, no proxy will have an instance of this object's configuration,        // but will have an independent copy.        if (logger.isTraceEnabled()) {            logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);        }        ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());        // The copy needs a fresh advisor chain, and a fresh TargetSource.        TargetSource targetSource = freshTargetSource();        copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain());        if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {            // Rely on AOP infrastructure to tell us what interfaces to proxy.            copy.setInterfaces(                    ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));        }        copy.setFrozen(this.freezeProxy);        if (logger.isTraceEnabled()) {            logger.trace("Using ProxyCreatorSupport copy: " + copy);        }        return getProxy(copy.createAopProxy());    }    protected final synchronized AopProxy createAopProxy() {        if (!this.active) {            activate();        }        return getAopProxyFactory().createAopProxy(this);    }    // DefaultAopProxyFactory.java    @Override    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.");            }            // 如果是接口类或是是代理类,使用jdk动态代理            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {                return new JdkDynamicAopProxy(config);            }            return new ObjenesisCglibAopProxy(config);        }        else {            return new JdkDynamicAopProxy(config);        }    }// 根据aopPorxy是哪种代理方式决定不同的生成object方式protected Object getProxy(AopProxy aopProxy) {        return aopProxy.getProxy(this.proxyClassLoader);    }
    //AdvisorSupport.java    //以下代码主要功能在于将获取的advisor添加到advisors链表中,辅以清除缓存    @Override    public void addAdvisor(Advisor advisor) {        int pos = this.advisors.size();        addAdvisor(pos, advisor);    }    @Override    public void addAdvisor(int pos, Advisor advisor) throws AopConfigException {        if (advisor instanceof IntroductionAdvisor) {            validateIntroductionAdvisor((IntroductionAdvisor) advisor);        }        addAdvisorInternal(pos, advisor);    }    private void addAdvisorInternal(int pos, Advisor advisor) throws AopConfigException {        Assert.notNull(advisor, "Advisor must not be null");        if (isFrozen()) {            throw new AopConfigException("Cannot add advisor: Configuration is frozen.");        }        if (pos > this.advisors.size()) {            throw new IllegalArgumentException(                    "Illegal position " + pos + " in advisor list with size " +         this.advisors.size());        }        this.advisors.add(pos, advisor);        updateAdvisorArray();        adviceChanged();    }    /**     * Bring the array up to date with the list.     */    protected final void updateAdvisorArray() {        this.advisorArray = this.advisors.toArray(new Advisor[this.advisors.size()]);    }    protected void adviceChanged() {        this.methodCache.clear();    }

下面就是jdk动态代理和cglib动态代理两种代理方式生成代理对象的过程:

  • jdk动态代理

    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);    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);        // 根据类装载器和接口通过反射生成代理类    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);}

  • cglib动态代理

    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 (Exception ex) {        // TargetSource.getTarget() failed        throw new AopConfigException("Unexpected AOP exception", ex);    }}

    以上是实现生成代理对象的过程,而拦截器的步骤在于两种代理的回调。那么接下来就深入分析执行回调代码达到拦截器的作用。

    2. 生成拦截链

    以jdk动态代理回调为例,来看怎么为目标对象生成拦截链

    生成拦截链

// jdk动态代理的回调方法@Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        MethodInvocation invocation;        Object oldProxy = null;        boolean setProxyContext = false;        // 获取目标代理对象        TargetSource targetSource = this.advised.targetSource;        Class<?> targetClass = null;        Object target = null;        try {            if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {                // 如果目标类没有实现equal,这里实现。                return equals(args[0]);            }            if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {                // 如果没有实现hashCode()                return hashCode();            }            if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&                    method.getDeclaringClass().isAssignableFrom(Advised.class)) {                // 通过反射调用方法并执行                return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);            }            Object retVal;            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 = targetSource.getTarget();            if (target != null) {                targetClass = target.getClass();            }            // 这里获取对象所有的拦截链            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);            // 如果没有拦截链,或者说没有对应的增强            if (chain.isEmpty()) {                // 直接使用反射执行对象方法                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);            }            else {                // 否则新建ReflectiveMethodInvocation,依次执行拦截链的方法                invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);                // Proceed to the joinpoint through the interceptor chain.                retVal = invocation.proceed();            }            // Massage return value if necessary.            Class<?> returnType = method.getReturnType();            if (retVal != null && retVal == target && returnType.isInstance(proxy) &&                    !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {                // Special case: it returned "this" and the return type of the method                // is type-compatible. Note that we can't help if the target sets                // a reference to itself in another returned object.                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);            }            return retVal;        }        finally {            if (target != null && !targetSource.isStatic()) {                // Must have come from TargetSource.                targetSource.releaseTarget(target);            }            if (setProxyContext) {                // Restore old proxy.                AopContext.setCurrentProxy(oldProxy);            }        }    }
// AdvisedSupport.java// 如果缓存中没有那么去生成拦截链public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {        MethodCacheKey cacheKey = new MethodCacheKey(method);        List<Object> cached = this.methodCache.get(cacheKey);        if (cached == null) {            cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(                    this, method, targetClass);            this.methodCache.put(cacheKey, cached);        }        return cached;    }
// DefaultAdvisorChainFactory.javapublic List<Object> getInterceptorsAndDynamicInterceptionAdvice(            Advised config, Method method, Class<?> targetClass) {        // This is somewhat tricky... We have to process introductions first,        // but we need to preserve order in the ultimate list.        List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);        Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());        boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();        for (Advisor advisor : config.getAdvisors()) {            if (advisor instanceof PointcutAdvisor) {                // Add it conditionally.                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {                  // 根据advisor获取拦截链                   MethodInterceptor[] interceptors = registry.getInterceptors(advisor);                  // 根据advisor切点获取匹配方法,即筛选可用的拦截链方法                  MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();                    if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {                        if (mm.isRuntime()) {                            // Creating a new object instance in the getInterceptors() method                            // isn't a problem as we normally cache created chains.                            for (MethodInterceptor interceptor : interceptors) {                                interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));                            }                        }                        else {                            interceptorList.addAll(Arrays.asList(interceptors));                        }                    }                }            }            else if (advisor instanceof IntroductionAdvisor) {                IntroductionAdvisor ia = (IntroductionAdvisor) advisor;                if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {                    Interceptor[] interceptors = registry.getInterceptors(advisor);                    interceptorList.addAll(Arrays.asList(interceptors));                }            }            else {                Interceptor[] interceptors = registry.getInterceptors(advisor);                interceptorList.addAll(Arrays.asList(interceptors));            }        }        return interceptorList;    }
// DefaultAdvisorAdapterRegistry.java// 根据adviceadapter找到对应的interceptorpublic MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {        List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);        Advice advice = advisor.getAdvice();        if (advice instanceof MethodInterceptor) {            interceptors.add((MethodInterceptor) advice);        }        for (AdvisorAdapter adapter : this.adapters) {            if (adapter.supportsAdvice(advice)) {                interceptors.add(adapter.getInterceptor(advisor));            }        }        if (interceptors.isEmpty()) {            throw new UnknownAdviceTypeException(advisor.getAdvice());        }        return interceptors.toArray(new MethodInterceptor[interceptors.size()]);    }
// MethodBeforeAdviceAdapter@Override    public boolean supportsAdvice(Advice advice) {        return (advice instanceof MethodBeforeAdvice);    }    // 根据advice获取对应的interceptor    @Override    public MethodInterceptor getInterceptor(Advisor advisor) {        MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();        return new MethodBeforeAdviceInterceptor(advice);    }

3.实现advice中的增强

实现增强功能

关键在与通过以下操作,实现增强功能的实现

    invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);    retVal = invocation.proceed();
// ReflectiveMethodInvocation.javaprotected ReflectiveMethodInvocation(            Object proxy, Object target, Method method, Object[] arguments,            Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {        this.proxy = proxy;        this.target = target;        this.targetClass = targetClass;        this.method = BridgeMethodResolver.findBridgedMethod(method);        this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);        this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;    }public Object proceed() throws Throwable {        //  从index为-1开始执行。如果执行到拦截链最末端,则通过反射执行对象方法        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {            return invokeJoinpoint();        }        // 依次获取拦截链中的拦截器        Object interceptorOrInterceptionAdvice =                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {            // 动态匹配方法再次匹配            InterceptorAndDynamicMethodMatcher dm =                    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;            if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {                // 如果匹配则调用拦截器的invoke方法                return dm.interceptor.invoke(this);            }            else {                // 匹配不了,继续向下递归执行                return proceed();            }        }        else {            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);        }    }
// 以methodBeforeAdvice为例看增强的调用public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {    private MethodBeforeAdvice advice;    /**     * Create a new MethodBeforeAdviceInterceptor for the given advice.     * @param advice the MethodBeforeAdvice to wrap     */    public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {        Assert.notNull(advice, "Advice must not be null");        this.advice = advice;    }    // 回调invoke方法,调用advice中实现的增强before方法,再调用proceed,保证拦截链的向下执行    @Override    public Object invoke(MethodInvocation mi) throws Throwable {        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );        return mi.proceed();    }}
// AfterReturningAdvice也同样,唯一不同的是先执行拦截链方法,再执行本身advice的回调增强方法// 从而实现运行在目标增强方法后的情况public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {    private final AfterReturningAdvice advice;    /**     * Create a new AfterReturningAdviceInterceptor for the given advice.     * @param advice the AfterReturningAdvice to wrap     */    public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {        Assert.notNull(advice, "Advice must not be null");        this.advice = advice;    }    @Override    public Object invoke(MethodInvocation mi) throws Throwable {        Object retVal = mi.proceed();        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());        return retVal;    }}

至此,完成advice的增强功能,整个aop实现完成。

小结

通过以上源码分析,已经从头到尾的梳理过AOP实现的整个功能:

  1. 获取配置信息生成advisor链。
  2. 根据不同情况区分使用jdk动态代理或者cglib动态代理。
  3. 根据advisor链中的切点和增强(advice)生成拦截链。
  4. 递归运行拦截链,判断动态匹配规则是否匹配。并根据增强不同串联上增强回调方法。

此时返回的aop代理对象,调用方法时,就回按照增强顺序依次调用增强方法和初始对象方法,实现了AOP增强的功能。

原创粉丝点击