• spring---aop(8)---Spring AOP中optimize


    写在前面

      optimize是ProxyConfig的属性。意思为 是否对生产代理策略使用优化。

    public class ProxyConfig implements Serializable {
        private boolean proxyTargetClass = false;
        private boolean optimize = false;
        boolean opaque = false;
        boolean exposeProxy = false;
        private boolean frozen = false;
    }

    一个例子

      Spring AOP 提供一个可根据Bean名称来自动生产代理的工具,它就是BeanNameAutoProxyCreator。它的配置是这样:

        <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
            <property name="beanNames" value="*impl"></property>  <!-- 只为后缀为"impl"的bean生产代理 -->
            <property name="interceptorNames" value="aServiceAdvisor"></property>   <!-- 一个增强 -->
            <property name="optimize" value="true"></property>   <!-- 是否对代理策略进行优化 -->
        </bean>

      以上使用BeanNameAutoProxyCreator 只为后缀为"impl"的Bean生产代理。需要注意的是,这个地方我们不能定义代理接口,也就是interfaces属性,因为我们根本就不知道这些Bean到低实现了多少接口。此时不能代理接口,而只能代理类。所以这里提供了一个新的配置项,它就是optimize。如果为true,则可以对代理生成策略进行优化(默认为false)。也就是说,如果该类有接口,就代理接口(使用JDK代理);如果没有接口,就代理类(使用CGLIB代理)。并非像之前的使用的proxyTargetClass 属性那样,强制代理类,而不去考虑代理接口的方式。

      那么就有一个问题了,既然有了CGLIB 可以代理任何类了,那为什么还要JDK的动态代理了?

      是因为CGLIB 创建有个特点(创建慢,执行块),然而JDK刚好相反(创建快,执行慢)。如果在运行的时候不断的用CGLIB去创建代理,系统的性能会大打折扣,所以建议一般在系统初始化的使用用CGLIB去创建代理,并放入spring的ApplicationContext中以备后用。

    流程分析

        @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() || Proxy.isProxyClass(targetClass)) {
                    return new JdkDynamicAopProxy(config);
                }
                return new ObjenesisCglibAopProxy(config);
            }
            else {
                return new JdkDynamicAopProxy(config);
            }
        }

    ProxyTargetClass (是否强制使用CGLIB来实现代理)

             (true : 强制使用CGLIB来实现代理)

             (false : 不强制使用CGLIB来实现代理,首选JDK来实现代理)(默认值)

    isOptimize (是否对生成代理策略进行优化)

             (true :  进行优化,如果有接口就代理接口(使用JDK动态代理),没有接口代理类(CGLIB代理))

             (false : 不进行优化) (默认值)

  • 相关阅读:
    spring+mybatis的多源数据库配置实战
    AspectJ的拓展学习--织入顺序和通知参数指定
    类Shiro权限校验框架的设计和实现(2)--对复杂权限表达式的支持
    权限系统(RBAC)的数据模型设计
    类Shiro权限校验框架的设计和实现
    springmvc简单集成shiro
    利用Aspectj实现Oval的自动参数校验
    Dubbo的全局Filter配置
    Dubbo的Filter实战--整合Oval校验框架
    Dubbo的Filter链梳理---分组可见和顺序调整
  • 原文地址:https://www.cnblogs.com/chihirotan/p/7363761.html
Copyright © 2020-2023  润新知