在spring中获取代理对象代理的目标对象工具类

问题描述::

我现在遇到个棘手的问题,要通过spring托管的service类保存对象,这个类是通过反射拿到的,经过实验发现这个类只能反射取得sservice实现了接口的方法,而extends类的方法一律不出现,debug后发现这个servie实例被spring替换成jdkdynmicproxy类,而不是原始对象了,,它里面只有service继承的接口方法,而没有extends 过的super class方法,怎么调用原生对象的方法!!!!!

用托管的spring service类调用getClass().getName()方法,发现输出都是$proxy43这类东西!!

通过此种方式获取目标对象是不可靠的,或者说任何获取目标对象的方式都是不可靠的,因为TargetSource,TargetSource中存放了目标对象,但TargetSource有很多种实现,默认我们使用的是SingletonTargetSource ,但还有其他的比如ThreadLocalTargetSource、CommonsPoolTargetSource 等等。

这也是为什么spring没有提供获取目标对象的API。

Java代码  

  1. import java.lang.reflect.Field;
  2. import org.springframework.aop.framework.AdvisedSupport;
  3. import org.springframework.aop.framework.AopProxy;
  4. import org.springframework.aop.support.AopUtils;
  5. public class AopTargetUtils {
  6. /**
  7. * 获取 目标对象
  8. * @param proxy 代理对象
  9. * @return
  10. * @throws Exception
  11. */
  12. public static Object getTarget(Object proxy) throws Exception {
  13. if(!AopUtils.isAopProxy(proxy)) {
  14. return proxy;//不是代理对象
  15. }
  16. if(AopUtils.isJdkDynamicProxy(proxy)) {
  17. return getJdkDynamicProxyTargetObject(proxy);
  18. } else { //cglib
  19. return getCglibProxyTargetObject(proxy);
  20. }
  21. }
  22. private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
  23. Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
  24. h.setAccessible(true);
  25. Object dynamicAdvisedInterceptor = h.get(proxy);
  26. Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
  27. advised.setAccessible(true);
  28. Object target = ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
  29. return target;
  30. }
  31. private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
  32. Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
  33. h.setAccessible(true);
  34. AopProxy aopProxy = (AopProxy) h.get(proxy);
  35. Field advised = aopProxy.getClass().getDeclaredField("advised");
  36. advised.setAccessible(true);
  37. Object target = ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget();
  38. return target;
  39. }
  40. }
时间: 2024-10-04 14:38:25

在spring中获取代理对象代理的目标对象工具类的相关文章

手动从Spring中获取指定对象

1.创建ApplicationContext对象: ApplicationContext context = new FileSystemXmlApplicationContext("D:/workspace/test/resources/applicationContext-resource.xml"); 2.调用getBean方法(注意参数以xml配置中的bean的名字匹配):     trDAO = (ITestResultDAO) context.getBean("t

Spring中获取被代理的对象

目录 Spring中获取被代理的对象 获取Spring被代理对象什么时候可能会用到? Spring中获取被代理的对象 Spring中获取被代理的对象 ### 获取Spring被代理对象的JAVA工具类 ? Spring采用CGLIB或者JDK动态代理来实现AOP,那如何获取 被代理对象?通过ApplicationContext.getBean()获取到的对象都是 利用字节码动态生成的 增强对象,那假如我们有场景获取 被代理的对象,方式如下: (封装到工具类形式里面,直接通过getTrueTarg

Spring中的JDK动态代理

Spring中的JDK动态代理 在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层技术. JDK的动态代理主要涉及Java.lang.reflect包中的两个类:Proxy和InvocationHandler.其中InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编织在一起.而Proxy为Invo

获取JDK动态代理/CGLIB代理对象代理的目标对象。

问题描述:: 我现在遇到个棘手的问题,要通过spring托管的service类保存对象,这个类是通过反射拿到的,经过实验发现这个类只能反射取得sservice实现了接口的方法,而extends类的方法一律不出现,debug后发现这个servie实例被spring替换成jdkdynmicproxy类,而不是原始对象了,,它里面只有service继承的接口方法,而没有extends 过的super class方法,怎么调用原生对象的方法!!!!! 用托管的spring service类调用getCl

Spring中的cglib动态代理

Spring中的cglib动态代理 cglib:Code Generation library, 基于ASM(java字节码操作码)的高性能代码生成包 被许多AOP框架使用 区别于JDK动态代理,cglib不需要实现接口. 下面使用cglib动态代理的方法实现增强 步骤一:创建一个接口UserService public interface UserService { public void delect(); } 步骤二:创建一个UserService接口的实现类UserServiceImpl

spring中获取dao或对象中方法的实例化对象

spring中获取dao的中方法的实例化对象: 1 //获取应用上下文对象 2 ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml"); 3 //例子:获取dicDao实例 4 dicDao = ctx.getBean(IDicDao.class); //例子2:获取MemcacheAccess的实例: 5 memcachedAccess = ctx.getBean(Memcach

spring中获取applicationContext

常用的5种获取spring 中bean的方式总结: 方法一:在初始化时保存ApplicationContext对象代码:ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");ac.getBean("beanId");说明:这种方式适用于采用Spring框架的独立应用程序,需要程序通过配置文件手工初始化Spring的情况. 方法二:通过Spring提供

Spring 中获取 request 的几种方法,及其线程安全性分析

概述在使用Spring MVC开发Web系统时,经常需要在处理请求时使用request对象,比如获取客户端ip地址.请求的url.header中的属性(如cookie.授权信息).body中的数据等.由于在Spring MVC中,处理请求的Controller.Service等对象都是单例的,因此获取request对象时最需要注意的问题,便是request对象是否是线程安全的:当有大量并发请求时,能否保证不同请求/线程中使用不同的request对象.这里还有一个问题需要注意:前面所说的"在处理请

在SpringMVC中获取request对象的几种方式

1.最简单的方式(注解法) 1 2 @Autowired private  HttpServletRequest request; 2.最麻烦的方法 a. 在web.xml中配置一个监听 <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener> b.之后在程序里可以用 Http

在SpringMVC中获取request对象

1.注解法 Java代码   @Autowired private  HttpServletRequest request; 2. 在web.xml中配置一个监听 Xml代码   <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener> 之后在程序里可以用 Java代码   H