`
jaesonchen
  • 浏览: 311658 次
  • 来自: ...
社区版块
存档分类
最新评论

cglib动态代理实现(持有业务类对象)

 
阅读更多
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 ..

分享到:
评论

相关推荐

    Java动态代理详解; CGLib实现动态代理1

    动态代理提供了在运行时动态创建代理对象的能力,而 CGLib 使得代理机制可以应用于没有接口的类,提高了代码的灵活性和可扩展性。通过代理模式,我们可以将业务逻辑与辅助功能分离,让代码更加模块化,便于维护和...

    四、Spring源码分析——动态代理

    - **CGLIB代理**:如果目标对象没有实现任何接口,Spring会使用CGLIB库生成一个目标对象的子类,通过子类来实现方法拦截。CGLIB是通过ASM库在运行时动态生成字节码来创建代理类的。 3. **AOP代理的理解** 在...

    动态代理实现aop

    - **CGLIB动态代理**:使用第三方库CGLIB来实现代理,可以为没有实现接口的类创建代理。 #### 示例分析 在给定的部分代码示例中,我们可以看到一个简单的AOP实现过程: 1. **定义接口**:首先定义了一个接口`...

    代理模式及动态代理资料和源代码

    它可以基于JDK动态代理(如果目标类实现了接口)或CGLIB(如果目标类没有接口)。Spring AOP代理可以在方法调用前后自动插入切面逻辑,如事务管理、性能监控等。 5. **代理模式的角色** - **Subject(主题)**:...

    springAOP之代理模式.docx

    当被代理类没有接口或者接口数量过多时,可以使用CGLib生成子类作为代理,实现对被代理类的扩展。 Spring AOP在默认情况下使用JDK动态代理,但当目标类没有接口时,会自动切换到CGLib。通过动态代理,Spring可以在...

    spring 的代理机制

    静态代理是程序员手动创建一个代理类,该类扩展或实现与原始业务类相同的接口,并在代理类的方法中调用实际业务逻辑,同时插入额外的行为。例如在给定的例子中,`StudentServiceImpl` 实现了 `IStudentService` 接口...

    java动态代理1

    Spring AOP通过代理模式实现了切面的织入,可以使用JDK动态代理或CGLIB代理(对于没有实现接口的类)来创建代理对象。 总结来说,Java动态代理是通过`InvocationHandler`和`Proxy`类实现的,它让我们能够在运行时...

    20190606_SpringAOP编程实现_田超凡.docx

    CGLIB代理通过创建目标类的子类并在子类中加入增强代码来实现AOP。 4. **Spring AOP的应用** Spring AOP允许开发者定义“切面”(Aspect),这些切面封装了横切关注点。在Spring中,可以使用XML配置或者注解来声明...

    代理模式

    动态代理主要有JDK动态代理和CGLIB动态代理两种实现方式。 在《代理模式》这篇博客中,作者可能详细解释了代理模式的概念、作用、适用场景以及如何在Java中实现静态代理和动态代理。此外,可能还探讨了代理模式与...

    Spring AOP里的静态代理和动态代理用法详解

    代理是一种设计模式,通过创建一个代理对象来控制对委托类对象的直接访问,隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间。 静态代理是一种静态创建的代理对象,在编译期生成代理类的.class文件。静态...

    Java的三种代理模式.docx

    在静态代理中,代理对象会持有目标对象的引用,并通过调用目标对象的方法来完成实际的业务逻辑。这种方式的优点是可以在不修改目标对象的前提下扩展其功能。然而,静态代理的缺点也比较明显:当接口方法增加时,目标...

    Spring模拟aop静态代理案例

    这个代理类会持有目标对象的引用,并在调用目标对象的方法之前和之后添加额外的操作,如记录日志或验证权限。 4. 分配职责:在代理类的`execute()`方法中,先进行预处理(如日志记录),然后调用目标对象的`execute...

    Spring动态代理一.docx

    总结来说,Spring的动态代理机制在Dao层和服务层都发挥着关键作用,它简化了对象创建和管理,实现了事务控制,同时也提供了AOP功能,使得开发者能够专注于业务逻辑,而无需关心底层的细节。这种设计极大地提高了代码...

    Spring学习笔记(12)----静态代理模式分析演示

    而对于非接口类,Spring会自动切换到CGLIB代理。 在实际应用中,我们通常不会直接使用静态代理模式,而是通过Spring的AOP配置来实现。例如,我们可以定义一个切面类,其中包含切点表达式和通知方法。切点表达式定义...

    深入浅析Spring AOP的实现原理1

    Spring AOP也支持基于CGLIB的动态代理,当目标类不实现接口时,Spring会自动切换到CGLIB代理。 Spring AOP的实现原理包括以下几个关键点: 1. **切面(Aspect)**:切面是AOP的核心,它封装了特定的横切关注点,如...

    spring+静态代理

    在Spring框架中,虽然动态代理(如JDK动态代理或CGLIB代理)更常见,因为它们可以自动创建代理对象,但静态代理也有其应用场景,特别是当需要在不依赖Spring的情况下,或者对性能有较高要求时。 要实现Spring框架下...

    Java spring AOP源码

    - **CGLIB动态代理**:通过继承目标类的方式创建代理对象,通常用于非接口的场景。 **4. **Spring AOP中的拦截器链** Spring AOP通过构建一个拦截器链(interceptor chain)来实现方法的增强。每个拦截器都有机会...

    深入浅析Spring 的aop实现原理

    6. **代理创建**:Spring根据目标类是否实现接口选择使用JDK动态代理或CGLIB动态代理创建代理对象。代理对象在调用目标方法时,会执行相应的通知逻辑。 7. **使用代理对象**:在应用中,不再直接调用目标对象,而是...

Global site tag (gtag.js) - Google Analytics