写在前面

  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 : 不进行优化) (默认值)

最新文章

  1. Installshield调用DLL的正确姿势
  2. mysql系统数据库
  3. pymssql examples
  4. js兼容方法:通过样式名获取元素,byClass
  5. Fliwer:监控植物状态 实现远程浇水
  6. c++ 函数调用在进入下一个循环的时候会再次初始化参数,将函数体直接写进去就正常
  7. 通过ajax提交form表单
  8. ubuntu 上使用apt-get安装oracle-jdk
  9. POJ 3678 Katu Puzzle (2-SAT,常规)
  10. macbook安装mysql
  11. java入门知识
  12. 1132: 零起点学算法39——多组测试数据(a+b)
  13. JavaScript 创建一个 form 表单并提交
  14. Ajax的简单实用实例
  15. NYOJ--122--Triangular Sums
  16. 项目案例【Net Core】如何注入多个服务实现类
  17. 编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第4章编程练习1
  18. 深入浅出的webpack构建工具---HappyPack优化构建(九)
  19. hdu-2709整数划分 技巧
  20. Webhook是什么、怎么理解

热门文章

  1. RedisTemplate使用
  2. R语言以及RStdio的安装
  3. python进阶学习之匿名函数lambda
  4. (五)动态SQL
  5. CF GYM100548 (相邻格子颜色不同的方案数 2014西安现场赛F题 容斥原理)
  6. Spark(九)Spark之Shuffle调优
  7. 成功实施的APS项目故事分享---如何管理与激励APS项目团队
  8. shell在linux里摇摇晃晃
  9. python的简介(一)
  10. Ionic入门七:ionic tab(选项卡)