spring源码阅读(四)-Spring AOP源码阅读

调试源码

因为springAOP 有很多种配置,我这里只阅读一种 最常用的写法的源码

1.接口定义

public interface StudentService {
    public Integer  del(Long id);

    public boolean delAll();
}

2.实现类

public class StudentServiceImpl implements StudentService {

    @Override
    public Integer del(Long id) {
        System.out.println(String.format("执行删除id为:%s的数据",id));
        return 1;
    }

    @Override
    public boolean delAll() {
        System.out.println("删除所有数据");
        return true;
    }
}

3.拦截器

public class OperationInterceptor  implements MethodInterceptor {
    /**
     * 拦截的方法
     */
    List<String> refuseMethod= Arrays.asList("delAll");
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        if(refuseMethod.contains(invocation.getMethod().getName())){
            throw new Exception("无权访问");
        }
        return invocation.proceed();
    }
}

4.xml配置

    <bean name="studentServiceImpl"  class="org.springframework.lq.service.StudentServiceImpl"></bean>
    <!--配置Interceptor-->
    <bean name="operationInterceptor" class="org.springframework.lq.aspect.OperationInterceptor">
    </bean>
    <!--配置实现studentServiceImpl的代理-->
    <bean  class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="beanNames" value="*ServiceImpl"></property>
        <!--配置拦截器 这里可以配置advice advisor interceptor-->
        <property name="interceptorNames">
            <list>
                <value>operationInterceptor</value>
            </list>
        </property>
    </bean>

前面说过Spring AOP 是运行时基于 JDK代理和CGLIB代理实现,是在IOC的基础上实现的,根据前面的IOC源码 让我们猜猜在IOC中的代理时机。

根据IOC源码代理切入时机

时机1:ioc源码<23>

如果实现了InstantiationAwareBeanPostProcessor的方法postProcessBeforeInstantiation 并返回对象 将不走后续流程 直接返回此对象,我们在这里可以创建代理对象。

但是有个问题,就是未走后面的初始化和Aware逻辑直接返回,所以我们的依赖注入和成员变量初始化就没有值 显然不合理

  try {
            // 让 InstantiationAwareBeanPostProcessor 在这一步有机会替代对象。 此接口是BeanPostProcessor的子接口
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            //如果通过此扩展点创建了对象 则直接返回对象 不会执行下面createBean
            if (bean != null) {
                return bean;
            }
        }

时机2:ioc源码<27>

注入的源码我还没有看,但是再@Autowrit我们是否可以搞点事情,注入之前在注入对象创建代理然后注入

但是有个问题,每次注入都会创建一个代理,在通过容器getBean的时候拿到的还是原有对象 不可取

try {
            /**
             * 负责装配bean的属性 静态注入
             *<27> @Autowrit @Value动态注入 InstantiationAwareBeanPostProcessor
             *
             */
            populateBean(beanName, mbd, instanceWrapper);
            //<30>bean初始化完成后的各种回调
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }

时机3:ioc源码<30>

调用实现了BeanPostProcessor 接口的postProcessBeforeInitialization方法有机会返回代理对象 可以看到这里是合理的

if (mbd == null || !mbd.isSynthetic()) {
            //<32> BeanPostProcessor 的 postProcessBeforeInitialization 回调
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

时机4:ios源码的<34>

调用实现了BeanPostProcessor 接口的postProcessAfterInitialization方法有机会返回代理对象 这里是对象完全初始化和各种回调完毕的回调,可以看到这里比时机3更合理

if (mbd == null || !mbd.isSynthetic()) {
            //<34>BeanPostProcessor 的 postProcessAfterInitialization 回调
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

类图 

可以发现我们xml配置的BeanNameAutoProxyCreator

通过类图可以看出BeanNameAutoProxyCreator实现了 SmartInstantiationAwareBeanPostProcessor 间接实现BeanPostProcessor和InstantiationAwareBeanPostProcessor

时机1源码

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean

因为BeanNameAutoProxyCreator实现了InstantiationAwareBeanPostProcessor 我们先看这里是否有返回

 

结论:如果没有实现默认的TargetSource 这里不会生成代理类

  try {
            // <1>让 InstantiationAwareBeanPostProcessor 在这一步有机会替代对象。 此接口是BeanPostProcessor的子接口
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            //如果通过此扩展点创建了对象 则直接返回对象 不会执行下面createBean
            if (bean != null) {
                return bean;
            }
        }

<1>

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // Make sure bean class is actually resolved at this point.
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    //<2>
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    //如果自定义方法postProcessBeforeInstantiation创建了对象
                    if (bean != null) {
                        //调用当前BeanPostProcessor postProcessAfterInitialization方法
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

<2>

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            //判断是否是InstantiationAwareBeanPostProcessor 类型 如果是则调用判断是否是InstantiationAwareBeanPostProcessor 的postProcessBeforeInstantiation
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//<3> Object result
= ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }

<3>

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        Object cacheKey = getCacheKey(beanClass, beanName);

        /**
         * 根据缓存判断是否有生成过TargetSource
         * 如果生成过则直接返回null
         */
        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }
        /**
         * 是否有自定义生成TargetSource 默认没有实现 所以未生成代理 这里返回的是null
         */
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        /**
         * 如果有生成根据TargetSource 生成代理
         */
        if (targetSource != null) {
            if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
            }
            // 返回匹配当前 bean 的所有的 advisor、advice、interceptor
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            //<4>创建代理对象
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        return null;
    }

<4>

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

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

        /**
         * //根据配置判断用哪种代理
         *    // proxy-target-class="true",这样不管有没有接口,都使用 CGLIB 来生成代理:
         *    //   <aop:config proxy-target-class="true">......</aop:config>
         */
        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        ///这个方法会返回匹配了当前 bean 的 advisors 数组
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        // 扩展点,支持子类对ProxyFactory扩展
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }

        //<5>创建代理对象
        return proxyFactory.getProxy(getProxyClassLoader());
    }

<5>

org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)

    public Object getProxy(@Nullable ClassLoader classLoader) {
        //<6>工厂模式 根据配置获取jdk或者是cglib工厂AopProxy 再调用对应处理累的getProxy生成代理对象
        return createAopProxy().getProxy(classLoader);
    }

<6>

org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy

    protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            activate();
        }
        //先获取Factory 默认为 默认为DefaultAopProxyFactory <7>跟配置获取对应的ProxyFactory
        return getAopProxyFactory().createAopProxy(this);
    }

<7>

org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

        //根据配置判断是使用jdk 还是cglib
        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() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

时机3源码

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean

 if (mbd == null || !mbd.isSynthetic()) {
            //<8> BeanPostProcessor 的 postProcessBeforeInitialization 回调
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

<8>

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

@Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            //<9>
            Object current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

<9>

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInitialization

也没有代理 直接原对象返回

@Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }

时机4源码

if (mbd == null || !mbd.isSynthetic()) {
            //<10> BeanPostProcessor 的 postProcessAfterInitialization 回调
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

<10>

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        //获得实现了BeanPostProcessor的累的对象遍历调用postProcessAfterInitialization
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
               //<11>
            Object current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

<11>

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            //如果通过getEarlyObject方法创建了代理则返回
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                //<12>创建代理对象
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

<12>

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        //如果通过targetSource创建了bean
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        ////无需增强 下面 advisedBeans 可能此时还没有含有 cacheKey, 所以 get 出 null
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        //bean是为aop的基础设施类比如pointcut、advice、advisor类 || 增强类不需要创建代理
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // 查找bean的增强方法 advice advisor interceptor
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            //<4>创建代理
            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;
    }
posted @ 2020-11-17 16:40  意犹未尽  阅读(127)  评论(0编辑  收藏  举报