在Stackoverflow中有一个有趣的问题 ,关于Spring Bean如何获​​得对由Spring创建的代理的引用以处理事务,Spring AOP,缓存,异步流等。需要对代理的引用,因为如果存在对自身的调用通过代理bean,此调用将完全绕过代理。

考虑一个InventoryService接口:

public interface InventoryService{public Inventory create(Inventory inventory);public List<Inventory> list();public Inventory findByVin(String vin);public Inventory update(Inventory inventory);public boolean delete(Long id);public Inventory compositeUpdateService(String vin, String newMake);
}

还请考虑该服务的默认实现,并假设最后一个方法CompositeUpdateService内部在Bean本身上调用两个方法,如下所示:

public Inventory compositeUpdateService(String vin, String newMake) {logger.info("composite Update Service called");Inventory inventory = this.findByVin(vin);inventory.setMake(newMake);this.update(inventory);return inventory;
}

如果我现在创建一个方面来建议对InventoryService的任何调用,以跟踪每个方法调用花费的时间,Spring AOP将为InventoryService bean创建一个动态代理:

但是,对CompositeUpdateService的调用将仅在此方法的级别上记录时间,即CompositeUpdateService内部对findByVin的调用,update绕过了代理,因此不会被跟踪:

一个好的解决方法是使用AspectJ的全部功能– AspectJ会更改DefaultInventoryService的所有方法的字节码,以包括对建议的调用。

我们制定的解决方法是将对代理本身的引用注入到bean中,而不是调用this.findByVin和this.update,而是调用proxy.findByVin和proxy.update!

因此,现在我们如何将对代理的引用干净地注入到bean中-我提供的解决方案是创建一个接口,以标记对自己的代理感兴趣的bean:

public interface ProxyAware<T> {void setProxy(T proxy);
}

感兴趣的接口及其实现如下所示:

public interface InventoryService extends ProxyAware<InventoryService>{
...
}public class DefaultInventoryService implements InventoryService{ ...private InventoryService proxy;@Overridepublic void setProxy(InventoryService proxy) {this.proxy = proxy;}
}

然后定义一个BeanPostProcessor注入这个代理!

public class ProxyInjectingBeanPostProcessor implements BeanPostProcessor, Ordered {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (AopUtils.isAopProxy((bean))){try {Object target = ((Advised)bean).getTargetSource().getTarget();if (target instanceof ProxyAware){((ProxyAware) target).setProxy(bean);}} catch (Exception e) {return bean;}}return bean;}@Overridepublic int getOrder() {return Integer.MAX_VALUE;}
}

不是最干净的实现,但是可以!

参考: http : //blog.springsource.org/2012/05/23/understanding-proxy-usage-in-spring/

参考: all和杂项博客中, JCG合作伙伴 Biju Kunjummen 引用了代理课程中的动态代理 。

翻译自: https://www.javacodegeeks.com/2012/07/reference-to-dynamic-proxy-in-proxied.html

在代理类中引用动态代理相关推荐

  1. 服务引用代理类_在代理类中引用动态代理

    服务引用代理类 在Stackoverflow中有一个有趣的问题 ,关于Spring Bean如何获​​得对由Spring创建的代理的引用以处理事务,Spring AOP,缓存,异步流等.需要对代理的引 ...

  2. java动态代理_Java中的动态代理一

    方法newProxyInstance介绍 这篇开始学Java中的动态代理部分,刚开始,我们不去了解什么是动态代理相关的概念,除了动态代理,还有静态代理.我们学习动态代理直接从学习一个方法开始,这个方法 ...

  3. 代理模式中的动态代理

    动态代理和静态对比基本思路是一致的,只不过动态代理功能更加强大,随着业务的扩展适应性更强.如果还以找对象为例,使用动态代理相当于是能够适应复杂的业务场景.不仅仅只是父亲给儿子找对象,如果找对象这项业务 ...

  4. netcore 中的动态代理与RPC实现(微服务专题)

    一.关于RPC的调用 1. 调用者(客户端Client)以本地调用的方式发起调用: 2. Client stub(客户端存根)收到调用后,负责将被调用的方法名.参数等打包编码成特定格式的能进行网络传输 ...

  5. Spring中的动态代理

    动态代理:指的就是通过一个代理对象来创建需要的业务对象,然后在这个代理对象中统一进行各种需求的处理. 学习完Spring后会发现,Spring中的AOP(面向方面编程:Aspect Oriented ...

  6. 吃透Java中的动态代理

    动态代理在Java中是很重要的一部分,在很多框架中都会用到,如Spring中的AOP.Hadoop中的RPC等.为此在这把我对Java中的动态代理的理解分享给大家,同时写了一个模拟AOP编程的实例.( ...

  7. spring中AOP动态代理的两种方式

    AOP动态代理的两种方式 Spring AOP动态代理的方式(spring的AOP默认是JDK Proxy) 浅谈这两种动态代理 JDK的动态代理,需要有实现接口 动态代理--JDK Proxy ⚫ ...

  8. 浅谈Spring中JDK动态代理与CGLIB动态代理

    前言 Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式 ...

  9. Java中三种代理方式—— 静态代理与两种动态代理的实现机制

    个人博客请访问 http://www.x0100.top 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现 ...

最新文章

  1. Facebook频谱图模型生成比尔·盖茨声音,性能完胜WaveNet、MAESTRO
  2. 【Android】Source Insight 基本用法 ( 导入 Android 源码 | 设置字体 | 显示行号 | 搜索功能 | 快捷键设置 )
  3. matlab添加多个legend
  4. Charles调试Https Android
  5. iref streams_如何利用Neo4j Streams并建立即时数据仓库
  6. 软考信息系统项目管理师_项目风险管理---软考高级之信息系统项目管理师019
  7. POJ 3279 Fliptile
  8. git add/rm/mv文件到暂存区
  9. centos安装msfconsole
  10. dwg如何转换成pdf?
  11. 编写优质嵌入式C程序
  12. python移动文件但不覆盖_怎么做到Python file重复写入之前的内容不被后写入的覆盖...
  13. webflux之reactor-Subscriber
  14. Vertica 常用命令
  15. MCV使用ExceptionFilter和log4net记录程序异常日志
  16. 基于php的开题报告,基于php的微信web应用开发开题报告.doc
  17. Microsoft Outlook 2019 for mac(电子邮件和日历工具) v16.45Beta中文激活版
  18. 使用HTML语言和CSS开发商业站点
  19. latex参考文献居中_LaTeX中参考文献管理以及注意事项
  20. IBM SPSS Statistics 26.0 for Linux Ubuntu 英/中文安装教程

热门文章

  1. 转:在eclipse中搭建maven工程(第二种方法)
  2. 赞扬别人团建评论_赞扬精心设计:基于属性的测试如何帮助我成为更好的开发人员...
  3. 在线maven托管_使用Amazon s3托管您的Maven工件
  4. swarm 容器_Oracle应用容器云上的WildFly Swarm
  5. java jigsaw_Java 9,Jigsaw,JPMS和模块:个人探索
  6. cli命令行界面 demo_Java命令行界面(第24部分):MarkUtils-CLI
  7. java 函数式编程 示例_功能Java示例 第1部分–从命令式到声明式
  8. sidecar_Spring Cloud Sidecar –节点初始化
  9. crud-table_我个人的CRUD故事-或我如何来到CUBA平台
  10. java日志使用_使用Java 8防止日志过宽