import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; //传入业务类实例作为目标对象。 public class BusinessCglibProxy2 implements MethodInterceptor { //拦截器持有真正的业务对象 private Object target; private BusinessCglibProxy2(Object target) { //保存业务对象 this.target = target; } //创建代理对象 public static Object getCglibProxy(Object target) { //创建一个织入器 Enhancer enhancer = new Enhancer(); //设置父类 enhancer.setSuperclass(target.getClass()); //设置需要织入的逻辑 enhancer.setCallback(new BusinessCglibProxy2(target)); // 创建代理对象 //使用织入器创建子类 return enhancer.create(); } //由于CGLIB可以不需要实现接口来实现动态代理,其原理是通过字节码生成类的一个子类来完成的, //那就有可能出现需要动态代理对象不存在一个无参构造函数, //那么CGLIB在生成子类并实例化时将会产生错误 //创建带参数的代理对象 //创建带参数的代理对象 public static Object getCglibProxy(Object target, Class<?>[] argClazz, Object[] args) { //创建一个织入器 Enhancer enhancer = new Enhancer(); //设置父类 enhancer.setSuperclass(target.getClass()); // 设置需要织入的逻辑 enhancer.setCallback(new BusinessCglibProxy2(target)); // 创建带参数的代理对象 //使用织入器创建子类 return enhancer.create(argClazz, args); } /** * obj:cglib动态生成的代理类实例,业务类的子类的实例 * method:业务类方法的引用 * args:调用参数数组 * proxy:代理类对业务类方法的代理引用,是业务类的方法的代理 */ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { //obj 是cglib动态生成的代理实例,是BusinessImpl的子类的实例 System.out.println("Cglib动态代理类:" + obj.getClass().getName()); System.out.println("Before " + method.getName() + " .."); //proxy 这里是BusinessImpl的service方法Method的代理 //因为动态生成的代理类是子类或者是实现类,proxy.invokeSuper(Object obj, Object[] args) //调用的是代理类obj的父类BusinessImpl的service方法。 //那么proxy.invoke(Object obj, Object[] args)方法是做什么的, //javadoc上说这个方法可以用于 相同类中的其他对象的方法执行, //也就是说这个方法中的obj需要传入相同一个类的另一个对象,否则会进入无限递归循环。 //Object result = proxy.invokeSuper(obj, args); Object result = method.invoke(this.target, args); System.out.println("End "+ method.getName() + " .."); return result; } public static void main(String[] args) { BusinessImpl proxy = (BusinessImpl) BusinessCglibProxy2.getCglibProxy(new BusinessImpl()); proxy.service(); //带参数的业务类 BusinessImpl proxy1 = (BusinessImpl) BusinessCglibProxy2.getCglibProxy(new BusinessImpl("jaesonchen"), new Class[] {String.class}, new Object[] {"jaesonchen"}); proxy1.service(); } }
* CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的
子类。
* CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,
性能比JDK强。
* CGLIB是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,
但因为采用的是继承,所以不能对final修饰的方法进行代理。
* CGLib采用非常底层的字节码技术,可以为一个类创建一个子类,并在子类中采用方法拦截的技术拦截
所有父类方法的调用,并顺势植入横切逻辑。
* 在我们实际开发当中,在使用动态代理进行方法请求拦截时,可能会需要判断调用的方法然后决定拦截
的逻辑,也就是同一个代理类在调用不同的方法时拦截的逻辑都不相同,CGLIB提供了CallbackFilter
来帮助我们实现这一功能。
输出为:
Cglib动态代理类:com.jaeson.javastudy.BusinessImpl$$EnhancerByCGLIB$$da38c639
Before service ..
service.id = default
End service ..
Cglib动态代理类:com.jaeson.javastudy.BusinessImpl$$EnhancerByCGLIB$$da38c639
Before service ..
service.id = jaesonchen
End service ..
相关推荐
动态代理提供了在运行时动态创建代理对象的能力,而 CGLib 使得代理机制可以应用于没有接口的类,提高了代码的灵活性和可扩展性。通过代理模式,我们可以将业务逻辑与辅助功能分离,让代码更加模块化,便于维护和...
- **CGLIB代理**:如果目标对象没有实现任何接口,Spring会使用CGLIB库生成一个目标对象的子类,通过子类来实现方法拦截。CGLIB是通过ASM库在运行时动态生成字节码来创建代理类的。 3. **AOP代理的理解** 在...
- **CGLIB动态代理**:使用第三方库CGLIB来实现代理,可以为没有实现接口的类创建代理。 #### 示例分析 在给定的部分代码示例中,我们可以看到一个简单的AOP实现过程: 1. **定义接口**:首先定义了一个接口`...
它可以基于JDK动态代理(如果目标类实现了接口)或CGLIB(如果目标类没有接口)。Spring AOP代理可以在方法调用前后自动插入切面逻辑,如事务管理、性能监控等。 5. **代理模式的角色** - **Subject(主题)**:...
当被代理类没有接口或者接口数量过多时,可以使用CGLib生成子类作为代理,实现对被代理类的扩展。 Spring AOP在默认情况下使用JDK动态代理,但当目标类没有接口时,会自动切换到CGLib。通过动态代理,Spring可以在...
静态代理是程序员手动创建一个代理类,该类扩展或实现与原始业务类相同的接口,并在代理类的方法中调用实际业务逻辑,同时插入额外的行为。例如在给定的例子中,`StudentServiceImpl` 实现了 `IStudentService` 接口...
Spring AOP通过代理模式实现了切面的织入,可以使用JDK动态代理或CGLIB代理(对于没有实现接口的类)来创建代理对象。 总结来说,Java动态代理是通过`InvocationHandler`和`Proxy`类实现的,它让我们能够在运行时...
CGLIB代理通过创建目标类的子类并在子类中加入增强代码来实现AOP。 4. **Spring AOP的应用** Spring AOP允许开发者定义“切面”(Aspect),这些切面封装了横切关注点。在Spring中,可以使用XML配置或者注解来声明...
动态代理主要有JDK动态代理和CGLIB动态代理两种实现方式。 在《代理模式》这篇博客中,作者可能详细解释了代理模式的概念、作用、适用场景以及如何在Java中实现静态代理和动态代理。此外,可能还探讨了代理模式与...
代理是一种设计模式,通过创建一个代理对象来控制对委托类对象的直接访问,隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间。 静态代理是一种静态创建的代理对象,在编译期生成代理类的.class文件。静态...
在静态代理中,代理对象会持有目标对象的引用,并通过调用目标对象的方法来完成实际的业务逻辑。这种方式的优点是可以在不修改目标对象的前提下扩展其功能。然而,静态代理的缺点也比较明显:当接口方法增加时,目标...
这个代理类会持有目标对象的引用,并在调用目标对象的方法之前和之后添加额外的操作,如记录日志或验证权限。 4. 分配职责:在代理类的`execute()`方法中,先进行预处理(如日志记录),然后调用目标对象的`execute...
总结来说,Spring的动态代理机制在Dao层和服务层都发挥着关键作用,它简化了对象创建和管理,实现了事务控制,同时也提供了AOP功能,使得开发者能够专注于业务逻辑,而无需关心底层的细节。这种设计极大地提高了代码...
而对于非接口类,Spring会自动切换到CGLIB代理。 在实际应用中,我们通常不会直接使用静态代理模式,而是通过Spring的AOP配置来实现。例如,我们可以定义一个切面类,其中包含切点表达式和通知方法。切点表达式定义...
Spring AOP也支持基于CGLIB的动态代理,当目标类不实现接口时,Spring会自动切换到CGLIB代理。 Spring AOP的实现原理包括以下几个关键点: 1. **切面(Aspect)**:切面是AOP的核心,它封装了特定的横切关注点,如...
在Spring框架中,虽然动态代理(如JDK动态代理或CGLIB代理)更常见,因为它们可以自动创建代理对象,但静态代理也有其应用场景,特别是当需要在不依赖Spring的情况下,或者对性能有较高要求时。 要实现Spring框架下...
- **CGLIB动态代理**:通过继承目标类的方式创建代理对象,通常用于非接口的场景。 **4. **Spring AOP中的拦截器链** Spring AOP通过构建一个拦截器链(interceptor chain)来实现方法的增强。每个拦截器都有机会...
6. **代理创建**:Spring根据目标类是否实现接口选择使用JDK动态代理或CGLIB动态代理创建代理对象。代理对象在调用目标方法时,会执行相应的通知逻辑。 7. **使用代理对象**:在应用中,不再直接调用目标对象,而是...