zoukankan      html  css  js  c++  java
  • 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;
        }
  • 相关阅读:
    spring学习之@SessionAttributes
    Spring MVC @SessionAttributes注解
    SpringBoot yml 配置 多配置文件,开发环境,生产环境配置文件分开
    java 常用集合list与Set、Map区别及适用场景总结
    JAVA中String.format的用法 格式化字符串,格式化数字,日期时间格式化,
    Spring注解详解@Repository、@Component、@Service 和 @Constroller
    使用idea 在springboot添加本地jar包的方法本地运行有效,一旦需要打jar就会报错,这就需要在
    使用idea 在springboot添加本地jar包的方法 部署的时候本地jar没有包含的解决方法
    IDEA 快速将spring boot项目打包成jar包,简单快速有效
    java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一
  • 原文地址:https://www.cnblogs.com/LQBlog/p/13995033.html
Copyright © 2011-2022 走看看