美文网首页
Spring4 Aop创建代理源码

Spring4 Aop创建代理源码

作者: sunpy | 来源:发表于2019-03-22 22:55 被阅读0次

    创建Aop代理开始位置

    AbstractAutowireCapableBeanFactory类之initializeBean方法

    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                @Override
                public Object run() {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }
    
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
    
        try {
            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()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }
    
    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {
        
        Object result = existingBean;
        // 遍历在BeanFactory中的BeanPostProcessor的集合
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
            // 执行后处理器
            result = beanProcessor.postProcessAfterInitialization(result, beanName);
            if (result == null) {
                return result;
            }
        }
        return result;
    }
    

    AbstractAutoProxyCreator类之postProcessAfterInitialization方法

    // 创建一个配置了拦截器的代理
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean != null) {
            // 使用类全名和name构造一个key,格式:beanClass.getName() + "_" + beanName
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                // 如果它适合被代理,那么需要封装指定bean
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
    

    说明:
    Aop本身通过实现BeanPostProcessor接口,而其代理的过程的实现是在Spring加载该Bean实例化前调用postProcessAfterInitialization方法。

    AbstractAutoProxyCreator类之wrapIfNecessary方法

    // 如果bean符合被代理的需要,那么将bean包装起来
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (beanName != null && 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;
        }
    
        // 如果存在增强方法则创建代理
        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;
    }
    

    说明:
    前面就是校验bean是否已经被处理过,或者干脆不需要增强。而真正开始创建代理是在getAdvicesAndAdvisorsForBean方法,至于给哪个bean生成代理等操作也都是从该方法开始的。

    AbstractAdvisorAutoProxyCreator类之findEligibleAdvisors方法

    // 寻找与beanClass合适的Advisor
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        // 调用父类方法加载配置文件中的AOP声明
        // 提取增强器Advisor(普通增强器、同步实例化增强器等)
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        // 寻找匹配的增强器
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        // 添加默认DefaultPointcutAdvisor
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }
    

    AnnotationAwareAspectJAutoProxyCreator类之findCandidateAdvisors方法,提取增强器Advisor

    @Override
    protected List<Advisor> findCandidateAdvisors() {
        // 找到spring的所有增强
        List<Advisor> advisors = super.findCandidateAdvisors();
        // 提取增强器Advisor,然后添加到Advisor的List中
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        return advisors;
    }
    

    AopUtils类之findAdvisorsThatCanApply方法,寻找匹配的增强器

    // 寻找匹配的增强器
    protected List<Advisor> findAdvisorsThatCanApply(
            List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
        
        ProxyCreationContext.setCurrentProxiedBeanName(beanName);
        try {
            // 过滤已经得到的advisors
            return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        }
        finally {
            ProxyCreationContext.setCurrentProxiedBeanName(null);
        }
    }
    
    
    // 寻找所有增强器中适用于当前class的增强器
    public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
        if (candidateAdvisors.isEmpty()) {
            return candidateAdvisors;
        }
        List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
        // 处理引介增强
        for (Advisor candidate : candidateAdvisors) {
            if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                eligibleAdvisors.add(candidate);
            }
        }
        boolean hasIntroductions = !eligibleAdvisors.isEmpty();
        for (Advisor candidate : candidateAdvisors) {
            // 引介增强已经处理
            if (candidate instanceof IntroductionAdvisor) {
                // already processed
                continue;
            }
            // 对于普通bean处理
            if (canApply(candidate, clazz, hasIntroductions)) {
                eligibleAdvisors.add(candidate);
            }
        }
        return eligibleAdvisors;
    }
    

    AbstractAutoProxyCreator类之createProxy方法,使用指定的Bean创建aop代理

    // 使用指定的Bean创建aop代理
    protected Object createProxy(
            Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
        
        ProxyFactory proxyFactory = new ProxyFactory();
        // 获取当前类中的相关属性
        proxyFactory.copyFrom(this);
    
        // 检查proxyTargetClass属性的设置,如果为false,那么采用jdk基于接口的jdk代理,
        // 如果为true,那么采用cglib代理
        if (!shouldProxyTargetClass(beanClass, beanName)) {
            // Must allow for introductions; can't just set interfaces to
            // the target's interfaces only.
            Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
            for (Class<?> targetInterface : targetInterfaces) {
                // 添加代理接口
                proxyFactory.addInterface(targetInterface);
            }
        }
    
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        for (Advisor advisor : advisors) {
            // 将Advisor封装加入到ProxyFactory中
            proxyFactory.addAdvisor(advisor);
        }
        
        // 设置要代理的类
        proxyFactory.setTargetSource(targetSource);
        // 定制代理,子类可以进一步封装
        customizeProxyFactory(proxyFactory);
        // 用来控制代理工厂被配置之后,是否还允许修改通知
        // 缺省值为false(即在代理被配置之后,不允许修改代理的配置)
        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
        // 获取代理
        return proxyFactory.getProxy(this.proxyClassLoader);
    }
    

    说明:

    1. 获取当前类中的属性。
    2. 添加代理接口。
    3. 封装Advisor并加入到ProxyFactory中。
    4. 设置要代理的类。
    5. Spring提供定制函数customizeProxyFactory,子类可以在该函数中进一步封装。
    6. 进行获取代理操作。

    DefaultAopProxyFactory类之createAopProxy方法,创建AopProxy代理对象

    // 创建代理简单工厂,依据配置创建代理对象
    public Object getProxy(ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }
    
    // 根据AdvisedSupport(Aop配置管理器),来获取对应的代理对象
    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        // proxyTargetClass:目标类本身被代理而不是目标类的接口
        // hasNoUserSuppliedProxyInterfaces:是否存在代理的接口
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            // 如果目标类为null,抛出异常
            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()) {
                return new JdkDynamicAopProxy(config);
            }
            // 创建cglib代理对象
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            // 创建Jdk代理对象
            return new JdkDynamicAopProxy(config);
        }
    }
    

    Aop创建代理策略:
    1.如果proxyTargetClass设置为false或者存在代理接口,那么直接创建Jdk代理对象,返回。
    2.否则如果目标类是接口,那么就创建Jdk代理对象,返回。
    3.如果上面都不满足,那么直接创建cglib代理对象,返回。


    设计模式思考:
    抽象产品(AopProxy)、具体产品(JdkDynamicAopProxy、ObjenesisCglibAopProxy),根据输入参数目标类,逻辑工厂(DefaultAopProxyFactory)判断逻辑,创建具体产品,实际返回抽象产品,简单工厂模式在此场景应用。

    相关文章

      网友评论

          本文标题:Spring4 Aop创建代理源码

          本文链接:https://www.haomeiwen.com/subject/nuwxvqtx.html