Spring源码解析:(七)AOP的实现

前言

上文中介绍了aop的思想和aop的使用及相关信息,本文将深入spring 中aop的源码实现。

正文

代理对象的生成时机

读者如果研读过ioc的源码后,应该了解到在aop的代理对象生成并不是在具体使用bean的时候调用getbean去生成,而是在ioc的bean初始化时候就已经完成。所以我们需要去定位到ioc中去寻求aop在什么时候进行代理的。

首先先访问AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object,
org.springframework.beans.factory.support.RootBeanDefinition)这个方法

/**
*
* 初始化Bean
包括Bean后置处理器初始化
Bean的⼀些初始化⽅法的执⾏init-method
Bean的实现的声明周期相关接⼝的属性注⼊
*/
protected Object initializeBean(final String beanName, final Object bean,
@Nullable RootBeanDefinition mbd) {
// 执⾏所有的AwareMethods
if (System.getSecurityManager() != null) {
	AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
		invokeAwareMethods(beanName, bean);
		return null;
		}, getAccessControlContext());
	}
else {
	invokeAwareMethods(beanName, bean);
	}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 执⾏所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前的处理器方法
	wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean,beanName);
	}
try {
	// 这⾥就开始执⾏afterPropertiesSet(实现了InitializingBean接口)方法和initMethod
	invokeInitMethods(beanName, wrappedBean, mbd);
	}
catch (Throwable ex) {
	throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),
		beanName, "Invocation of init method failed", ex);
	}
if (mbd == null || !mbd.isSynthetic()) {
	// 整个Bean初始化完成,执⾏后置处理器⽅法
	wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean,beanName);
	}
	return wrappedBean;
}

其次再追踪到AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization方法

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {
Object result = existingBean;
// 循环执行后置处理器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
	Object current = processor.postProcessAfterInitialization(result,beanName);
	if (current == null) {
		return result;
		}
	result = current;
	}
return result;
}

在这里插入图片描述
创建代理对象的后置处理器AbstractAutoProxyCreator#postProcessAfterInitialization

 @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String
            beanName) {
        if (bean != null) {
// 检查下该类是否已经暴露过了(可能已经创建了,比如A依赖B时,创建A时候,就会先去创建B。
// 当真正需要创建B时,就没必要再代理一次已经代理过的对象),避免重复创建
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

AbstractAutoProxyCreator#wrapIfNecessary

/**
* Wrap the given bean if necessary, i.e. if it is eligible for being
proxied.
* @param bean the raw bean instance
* @param beanName the name of the bean
* @param cacheKey the cache key for metadata access
* @return a proxy wrapping the bean, or the raw bean instance as-is
*/
 protected Object wrapIfNecessary(Object bean, String beanName, Object
            cacheKey) {
	// targetSourcedBeans包含,说明前⾯创建过
        if (StringUtils.hasLength(beanName) &&
                this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(),
                beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
	// Create proxy if we have advice.
	// 得到所有候选Advisor,对Advisors和bean的⽅法双层遍历匹配,最终得到⼀个
        List<Advisor>,即specificInterceptors
        Object[] specificInterceptors =
                getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
		// 重点,创建代理对象
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new
                            SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

终于找到了调用生成代理对象的时机,接下来继续看下关键的创建代理对象方法AbstractAutoProxyCreator#createProxy

/**
* Create an AOP proxy for the given bean.
* 为指定 bean 创建代理对象
*/
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)
                    this.beanFactory, beanName, beanClass);
        }
		// 创建代理的工作交给ProxyFactory
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);
		// 根据一些情况判断是否要设置proxyTargetClass=true
        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
		// 把指定和通过拦截对象合并, 并都适配成Advisor
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
		// 设置参数
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);
        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
		// 上次准备做完就开始创建代理
        return proxyFactory.getProxy(getProxyClassLoader());
    }

接着跟进到ProxyFactory中

public class ProxyFactory extends ProxyCreatorSupport {
        public Object getProxy(ClassLoader classLoader) {
        //ProxyFactory创建AopProxy, 然后用AopProxy创建Proxy, 所以这里重要的是看获取的AopProxy
        // 对象是什么,然后进去看怎么创建动态代理, 提供了两种:jdk proxy, cglib
            return createAopProxy().getProxy(classLoader);
        }
    }
     public class ProxyCreatorSupport extends AdvisedSupport {
        private AopProxyFactory aopProxyFactory;
        public ProxyCreatorSupport() {
            this.aopProxyFactory = new DefaultAopProxyFactory();
        }
        protected final synchronized AopProxy createAopProxy() {
            if (!this.active) {
                activate();
            }
        //先获取创建AopProxy的工厂, 再由此创建AopProxy
            return getAopProxyFactory().createAopProxy(this);
        }
        public AopProxyFactory getAopProxyFactory() {
            return this.aopProxyFactory;
        }
    }

流程就是用AopProxyFactory创建AopProxy, 再用AopProxy创建代理对象,这里的AopProxyFactory默
认是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) {
                    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);
                }
                return new ObjenesisCglibAopProxy(config);
            } else {
                return new JdkDynamicAopProxy(config);
            }
        }
        /**
* Determine whether the supplied {@link AdvisedSupport} has only the
* {@link org.springframework.aop.SpringProxy} interface specified (or no
`* proxy interfaces specified at all).
*/
 private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
        Class<?>[] interfaces = config.getProxiedInterfaces();
        return (interfaces.length == 0 || (interfaces.length == 1 &&
                SpringProxy.class.equals(interfaces[0])));
    }
}``
这⾥决定创建代理对象是用JDK Proxy,还是用 Cglib 了,最简单的从使用方面使用来说:设置
proxyTargetClass=true强制使用Cglib 代理,什么参数都不设并且对象类实现了接口则默认用JDK 代
理,如果没有实现接口则也必须用Cglib
ProxyFactory#getProxy(java.lang.ClassLoader)
------ CglibAopProxy#getProxy(java.lang.ClassLoader)

```java
  @Override
    public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isTraceEnabled()) {
            logger.trace("Creating CGLIB proxy: " + 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);
            // 配置 Cglib 增强
            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);
        // 生成代理类,并且创建一个代理类的实例
            return createProxyClassAndInstance(enhancer, callbacks);
        }
        catch (CodeGenerationException | IllegalArgumentException ex) {
            throw new AopConfigException("Could not generate CGLIB subclass of " +
                    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);
        }
    }

所以aop实现的整体调用流程如下:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#i
nitializeBean
调用
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#a
pplyBeanPostProcessorsAfterInitialization
调用
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProce
ssAfterInitialization(后置处理器AbstractAutoProxyCreator完成bean代理对象创建)
调用
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNec
essary
调用
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createPro
xy (在这一步把委托对象的aop增强和通过拦截进行合并,最终给代理对象)
调用
org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
调用
org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader
)

后话

本文详细的通过代码梳理了spring的aop的实现过程,希望能帮助读者深入理解的aop的实现和其思想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值