看到这个,觉得很有用,
有一个应用场景是:dorado7 中
它的前端向后端传数据用的就是Cglib代理,如果用它的全部框架,它后端用hibernate 去保存就会很好,因hibernate 也是用Cglib代理,但我的自已的程序里面是对Spring的JDBC作了一个封装,所以从前台传到后台后还是一个代理,在保存时就会有错误,所以要得到目标对象,用以下方法即可得到。
代码如下:
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;
}
}
源自:http://jinnianshilongnian.iteye.com/blog/1613222
分享到:
相关推荐
总结来说,JDK代理和Cglib代理都是为了在运行时动态创建代理对象,以扩展或修改已有对象的行为。选择哪种方式取决于具体的需求,如目标对象是否实现接口、性能要求、兼容性等因素。在实际开发中,Spring框架就同时...
在Java开发中,动态代理和CGLIB代理是两种常见的面向切面编程(AOP)实现方式,它们都用于在不修改原有代码的情况下,增强或扩展对象的功能。本篇文章将深入探讨JDK动态代理和CGLIB代理的区别,以及它们在实际应用中...
在 Spring AOP 框架中,默认情况下,Spring 会选择使用 JDK 动态代理,但是如果目标对象没有实现接口,Spring 就会选择使用 CGLIB 动态代理。这种机制可以确保 Spring AOP 框架可以代理任何类型的对象,无论它是否...
本文将深入探讨两种主要的Java代理实现:JDK动态代理和CGLIB代理。 一、JDK动态代理 JDK动态代理基于接口实现,它要求被代理的类必须实现至少一个接口。在运行时,Java会动态地创建一个新的类,这个类实现了与原始...
它基于接口来实现,因此只有当目标对象实现了至少一个接口时,才能使用JDK动态代理。 1. **原理**:JDK动态代理通过`Proxy.newProxyInstance()`方法创建代理对象,该方法接受三个参数:一个类加载器、一个接口数组...
总结起来,JDK动态代理适用于目标对象实现了接口的情况,而CGLIB代理则可以在没有接口的情况下进行代理。两者都可以实现运行时的代理,但适用场景不同,开发者可以根据具体需求选择适合的代理方式。在实际开发中,...
总结一下,JDK动态代理适用于目标对象实现了接口的情况,而CGlib则适用于未实现接口的类。两者在性能上,CGlib通常比JDK代理稍快,但创建代理的过程相对复杂。选择哪种代理方式取决于具体的需求和项目情况。了解并...
- **CGLIB代理**:CGLIB通过ASM生成一个继承自目标类的新类,这个新类覆盖了目标类的所有方法,并在这些方法内部调用拦截器链。在运行时,这个新类的实例作为代理对象。 5. **优缺点**: - JDK代理简单易用,但...
- **CGLIB代理**适用于目标类没有接口或者不希望修改原有接口的情况,其性能通常优于JDK代理,因为它是基于字节码生成的子类,而JDK代理需要反射调用接口方法。 在实际开发中,如Spring AOP框架就同时支持JDK和...
JDK动态代理基于Java的反射API,它要求被代理的目标对象必须实现一个或多个接口。JDK动态代理的核心类是`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`。`Proxy`类用于创建动态代理实例,而`...
**CGLIB代理**则是在运行时动态地生成字节码来创建目标对象的子类,因此它适用于没有接口的目标对象。CGLIB库是Spring框架默认使用的代理方式之一。使用CGLIB代理的基本步骤: 1. **引入CGLIB库**:在项目中添加...
2. CGLib代理项目: - src/main/java:包含目标类 - target/classes:编译后的class文件,包括目标类的class文件,以及由CGLib生成的子类class文件 - 测试代码:展示如何使用Enhancer创建代理对象并调用方法 这...
在Java中,我们可以使用JDK自带的动态代理或者第三方库如CGLIB、Javassist、ASM来实现。 **JDK动态代理**: JDK的动态代理主要依赖于`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`两个类。...
CGLib的优点是它可以代理任何类,无需目标对象实现接口,但相比JDK动态代理,它的运行效率较低,且由于生成了子类,可能会引起类加载和内存占用的问题。 **Spring AOP的应用**: 在Spring框架中,AOP主要用于日志...
在Spring框架中,当目标对象不支持JDK动态代理(即没有实现接口)时,CGLib就会被用来创建代理。CGLib通过创建目标类的子类并覆盖其方法来实现动态代理。使用CGLib的主要类有`net.sf.cglib.proxy.Enhancer`和`...
在代理类的方法中,我们可以添加额外的逻辑,比如日志、权限检查等,然后调用目标对象的相应方法。 ```java // 目标接口 interface Service { void doSomething(); } // 目标实现 class ServiceImpl implements ...
而CGLIB的使用稍微复杂一些,需要通过Enhancer类配置回调函数和目标对象,然后调用create()方法生成代理。 安全性方面,由于JDK动态代理遵循接口,所以在类型检查和编译时期就能发现问题。而CGLIB在运行时生成子类...
动态代理在Java编程中是一种非常重要的技术,它允许我们在运行时创建对象的代理,从而可以在不修改原有代码的情况下,为对象添加额外的功能。本压缩包包含关于三种主要的动态代理实现方式:JDK动态代理、CGLIB以及...
- 创建代理对象:根据选择的代理方式(JDK或Cglib),调用相应的生成代理对象的方法。 - 定义目标方法:定义被代理类的方法,这可以是接口中的方法,对于Cglib,也可以是任意非final的方法。 - 实现`...
在Java编程中,动态代理是一种强大的技术,它允许我们在运行时创建对象的代理,以便在调用实际方法之前或之后执行额外的操作。JDK和CGLIB是两种常用的实现Java动态代理的方式。本文将深入探讨这两个库以及它们的工作...