`

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

 
阅读更多
昨天晚上一哥们需要获取代理对象的目标对象,查找了文档发现没有相应的工具类,因此自己写了一个分享给大家。能获取JDK动态代理/CGLIB代理对象代理的目标对象。


问题描述::

我现在遇到个棘手的问题,要通过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

import java.lang.reflect.Field;  
  
import org.springframework.aop.framework.AdvisedSupport;  
import org.springframework.aop.framework.AopProxy;  
import org.springframework.aop.support.AopUtils;  
  
public class AopTargetUtils {  
  
      
    /** 
     * 获取 目标对象 
     * @param proxy 代理对象 
     * @return  
     * @throws Exception 
     */  
    public static Object getTarget(Object proxy) throws Exception {  
          
        if(!AopUtils.isAopProxy(proxy)) {  
            return proxy;//不是代理对象  
        }  
          
        if(AopUtils.isJdkDynamicProxy(proxy)) {  
            return getJdkDynamicProxyTargetObject(proxy);  
        } else { //cglib  
            return getCglibProxyTargetObject(proxy);  
        }  
          
          
          
    }  
  
  
    private static Object getCglibProxyTargetObject(Object proxy) throws Exception {  
        Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");  
        h.setAccessible(true);  
        Object dynamicAdvisedInterceptor = h.get(proxy);  
          
        Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");  
        advised.setAccessible(true);  
          
        Object target = ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();  
          
        return target;  
    }  
  
  
    private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {  
        Field h = proxy.getClass().getSuperclass().getDeclaredField("h");  
        h.setAccessible(true);  
        AopProxy aopProxy = (AopProxy) h.get(proxy);  
          
        Field advised = aopProxy.getClass().getDeclaredField("advised");  
        advised.setAccessible(true);  
          
        Object target = ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget();  
          
        return target;  
    }  
      
}  



Spring的aop代理对象都实现了Advised这个接口,可以直接将代理对象转成Advised类型后通过该接口提供的方法获取目标对象,我的项目使用这个方式来获取目标对象,貌似没什么问题

参考:http://jinnianshilongnian.iteye.com/blog/1613222
分享到:
评论

相关推荐

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

    本文将深入探讨如何在Spring中通过自定义工具类获取代理对象所代理的目标对象。 ### 核心概念:AOP与Spring Proxy 在理解如何获取目标对象之前,我们需要先了解Spring AOP的实现机制。Spring AOP主要通过动态代理...

    spring proxy代理模仿

    Spring AOP通过代理模式为我们提供了在运行时向目标对象添加拦截器或切面的能力,这在进行日志记录、性能监控、事务管理等场景下非常实用。 首先,让我们了解代理模式的基本概念。代理模式是一种设计模式,它为一个...

    动态代理接口并注册到spring容器

    在Java开发中,动态代理是一种强大...4. 实现BeanPostProcessor并覆盖postProcessBeforeInitialization方法,在Spring初始化过程中注册代理对象。 5. 其他组件通过@Autowired注解注入代理对象,实现对代理接口的调用。

    springAop默认代理方式.zip

    5. **代理的使用**:在应用中,我们通常不直接引用目标对象,而是通过ApplicationContext获取Bean,此时Spring会自动创建并返回相应的代理对象。这样,当我们调用代理对象的方法时,就会触发AOP代理逻辑。 6. **切...

    spring的FactoryBean增强我们的目标对象.rar

    描述中提到的“在获取目标类的时间我们将增强的代理类给返回”,实际上是指在Spring容器通过`FactoryBean`创建bean时,我们可以返回一个被代理的目标对象。通常,这个代理对象可能是通过AOP(面向切面编程)创建的,...

    jdk代理,cgib代理和spring后处理bean的关系

    在Java开发中,代理模式是一种常见的设计...`AopTargetUtils`类则是Spring AOP中一个重要的辅助工具,帮助我们在处理AOP代理时更好地操作目标对象。理解这些概念和工具对于深入掌握Spring框架和Java代理技术至关重要。

    spring动态代理

    Spring 动态代理是 Spring 框架中的一个重要特性,它允许我们在运行时自动生成代理对象,以便在方法调用前后执行额外的操作,比如事务管理、AOP(面向切面编程)等。动态代理主要涉及两个核心接口:`java.lang....

    在自定义spring aop中使用el获取拦截方法的变量值。

    标题中的“在自定义Spring AOP中使用EL获取拦截方法的变量值”指的是在Spring的面向切面编程(AOP)中,通过Expression Language(EL,表达式语言)来访问被拦截方法的局部变量值。这通常涉及到Spring的代理机制、...

    JDK动态代理 spring aop 的原理

    5. AOP代理的使用:当通过Spring的依赖注入(DI)获取到一个对象时,实际上得到的是一个代理对象。通过这个代理对象调用方法,Spring会自动插入预先定义好的通知逻辑。 总的来说,JDK动态代理是Spring AOP实现的...

    Spring源代码解析(五):Spring_AOP获取Proxy.doc

    本文将深入解析Spring AOP如何获取代理对象,即Proxy。 首先,我们需要理解AOP的核心概念: 1. **Advice**:通知,是切面实际执行的操作。在Spring中,Advice可以是Before、AfterReturning、AfterThrowing以及...

    Spring Aop Advise方法(增强方法) 中获取目标方法的参数

    - 代理(Proxy):Spring创建的对象,用于在实际调用目标方法之前和之后执行通知。 3. **获取目标方法参数**: - 在Spring AOP的通知中,我们可以使用`MethodInterceptor`接口的`invoke`方法或者自定义的`Advisor...

    使用代理实现简易的spring aop功能

    2. **创建代理对象(Proxy Object)**:代理对象是围绕目标对象创建的,它在调用目标对象的方法之前和之后执行额外的逻辑。在JDK动态代理中,我们通过实现`java.lang.reflect.InvocationHandler`接口并实现其`invoke...

    springAOP配置动态代理实现

    在需要调用目标方法的地方,使用Spring注入的bean,实际上就是在操作代理对象。 综上所述,通过理解Spring AOP的配置和动态代理机制,我们可以灵活地在项目中添加横切关注点,提升代码的模块化和可维护性。在实际...

    Spring.net Aop 例子

    3. 在应用启动时,使用Spring.NET容器加载配置,并从容器中获取代理对象。 4. 通过代理对象调用目标方法,观察AOP行为。 通过这个例子,你可以学习到如何在Spring.NET环境中实现AOP,理解动态代理的工作原理,并...

    Spring示例_Printer_Spring_AOP_Spring_Proxy

    7. 在需要使用`Printer`的地方,通过Spring的依赖注入获取到的是Spring创建的代理对象,而非原始的`ConcretePrinter`实例。 这个示例可以帮助开发者理解如何在实际项目中利用Spring AOP和代理来增强或修饰对象的...

    java 动态代理实例(JDK代理与CGLIB代理)

    5. **生成并获取代理对象**:调用`create`方法,生成代理对象。 在附件的"demo"中,可能包含了这两个代理方式的示例代码,包括如何创建和使用代理对象,以及如何在`InvocationHandler`或`MethodInterceptor`中添加...

    Java动态代理(Spring Aop原理)

    - 调用Spring容器获取代理对象,执行业务方法时,相应的通知方法会被自动插入。 通过Java动态代理和Spring AOP,开发者能够轻松地实现代码的解耦,提高可维护性和复用性。在实际开发中,理解这些原理并合理运用,...

    利用反射和代理实现简单的Spring

    `Proxy.newProxyInstance()`方法接受一个类加载器、接口数组和一个`InvocationHandler`,在调用代理对象的方法时,实际调用的是`InvocationHandler.invoke()`。 5. **元数据解析**:Spring使用`...

    通过动态代理模拟Spring AOP

    - 最后,通过Proxy.newProxyInstance()方法,传入目标接口、InvocationHandler实例以及加载器,生成代理对象。 2. **实现切面逻辑:** - 在InvocationHandler的invoke()方法中,我们可以获取到被调用的方法名、...

Global site tag (gtag.js) - Google Analytics