Java动态代理与CGLib代理实例解析

0 下载量 105 浏览量 更新于2024-10-24 收藏 8KB ZIP 举报
资源摘要信息:"在Java开发中,代理模式是一种常用的结构型设计模式,它主要用于控制对象的访问,增强对象的功能。Java提供了两种代理的实现方式:动态代理(Dynamic Proxy)和CGLIB代理。动态代理是由Java反射机制提供的,而CGLIB(Code Generation Library)是一个功能强大的第三方代码生成库,用于在运行时扩展Java类与实现Java接口。以下将详细阐述Java动态代理和CGLIB代理的概念、区别以及如何使用它们创建代理对象。 首先,我们来看动态代理的基本概念。动态代理是JDK提供的一个API,通过Proxy类和InvocationHandler接口来实现。Proxy类用于生成代理类,而InvocationHandler接口则定义了代理实例上的方法调用处理程序。使用动态代理需要满足以下条件: 1. 被代理的类必须实现一个接口。 2. 代理类是在运行时通过Proxy类的newProxyInstance()方法动态创建的。 3. 当代理对象的方法被调用时,会转发到InvocationHandler的invoke()方法上。 以下是一个使用动态代理的简单示例: ```java import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxyExample { interface SomeInterface { void doSomething(); } static class SomeClass implements SomeInterface { @Override public void doSomething() { System.out.println("Class method"); } } static class MyInvocationHandler implements InvocationHandler { private final Object target; public MyInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before invocation"); Object result = method.invoke(target, args); System.out.println("After invocation"); return result; } } public static void main(String[] args) { SomeInterface someInstance = new SomeClass(); SomeInterface proxyInstance = (SomeInterface) Proxy.newProxyInstance( SomeInterface.class.getClassLoader(), new Class<?>[]{SomeInterface.class}, new MyInvocationHandler(someInstance) ); proxyInstance.doSomething(); } } ``` 在这个示例中,我们首先定义了一个接口SomeInterface和它的实现类SomeClass。MyInvocationHandler类实现了InvocationHandler接口,并在invoke方法中编写了我们需要在方法调用前后执行的代码。最后,在main方法中我们创建了一个代理实例,并调用了它的doSomething方法。 接下来,我们来看CGLIB代理。与动态代理不同,CGLIB通过继承的方式来实现代理。使用CGLIB代理不需要被代理类实现接口,它是在运行时直接修改被代理类的字节码,从而生成子类。因此,CGLIB代理生成的代理类性能比动态代理更好。使用CGLIB的步骤包括: 1. 添加CGLIB的依赖到项目中。 2. 创建Enhancer类的实例,并设置其父类(被代理类)。 3. 通过setCallback方法设置回调函数,回调函数实现了MethodInterceptor接口。 4. 使用create方法创建代理类的实例。 以下是一个使用CGLIB代理的简单示例: ```java import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CglibProxyExample { static class SomeClass { public void doSomething() { System.out.println("Class method"); } } static class MyMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("Before invocation"); Object result = proxy.invokeSuper(obj, args); System.out.println("After invocation"); return result; } } public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(SomeClass.class); enhancer.setCallback(new MyMethodInterceptor()); SomeClass proxyInstance = (SomeClass) enhancer.create(); proxyInstance.doSomething(); } } ``` 在这个示例中,我们定义了一个SomeClass类,不需要实现任何接口。MyMethodInterceptor实现了MethodInterceptor接口,并在intercept方法中编写了我们需要在方法调用前后执行的代码。在main方法中,我们创建了Enhancer的实例,设置了需要代理的类以及回调函数,并通过create方法创建了代理类的实例,最后调用了doSomething方法。 最后,我们对比一下Java动态代理和CGLIB代理的不同: 1. 动态代理基于接口实现,CGLIB代理基于类继承。 2. 动态代理生成代理对象时需要被代理对象实现接口,CGLIB则不需要。 3. 动态代理的性能相对于CGLIB来说要差一些,因为CGLIB直接操作字节码生成类。 4. 如果被代理类没有实现接口,那么只能使用CGLIB代理。 通过以上示例和分析,可以看出Java动态代理和CGLIB代理各有优缺点,在实际开发中,需要根据具体需求和环境选择合适的代理方式。"