使用JDK和Cglib两种方式动态代理

来源:互联网 发布:linux bzero 编辑:程序博客网 时间:2024/06/03 16:37

一 使用JDK动态代理

这种方式,只能对接口进行动态代理,有一定的局限性;


接口:

package org.spring.test2;import java.util.Map;public interface UserService {void insert(Map<String,Object> param);}


接口实现类:

package org.spring.test2;import java.util.Map;public class UserServiceImpl implements UserService{@Overridepublic void insert(Map<String, Object> param) {System.out.println("in insert");}}


生成代理的类:

package org.spring.test2;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class UserServiceInvocationHandler implements InvocationHandler{private UserService userService;public UserServiceInvocationHandler(UserService userService){this.userService=userService;}@Overridepublic Object invoke(Object arg0, Method arg1, Object[] arg2)throws Throwable {System.out.println("前置增强!");Object invoke = arg1.invoke(userService, arg2);System.out.println("后置增强!");return invoke;}}


测试类:

package org.spring.test2;import java.lang.reflect.Proxy;public class Test {public static void main(String[] args) {UserService us=new UserServiceImpl();UserService usp = (UserService) Proxy.newProxyInstance(us.getClass().getClassLoader(), us.getClass().getInterfaces(), new UserServiceInvocationHandler(us));usp.insert(null);}}



二 使用Cglib动态代理

引入包:

<!-- cglib --><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.2.5</version></dependency>


目标类:

package org.spring.test3;import java.util.Map;public class UserServiceImpl  {public void insert(Map<String,Object> param){System.out.println("in insert");}}


生成代理的类:

package org.spring.test3;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 CglibProxy implements MethodInterceptor{private Enhancer enhancer=new Enhancer();public Object getProxy(Class clazz){enhancer.setSuperclass(clazz);enhancer.setCallback(this);return enhancer.create();}@Overridepublic Object intercept(Object arg0, Method arg1, Object[] arg2,MethodProxy arg3) throws Throwable {System.out.println("前置增强");Object res = arg3.invokeSuper(arg0, arg2);System.out.println("后置增强");return res;}}


测试类:

package org.spring.test3;public class Test {public static void main(String[] args) {CglibProxy proxy = new CglibProxy();UserServiceImpl us = (UserServiceImpl) proxy.getProxy(UserServiceImpl.class);us.insert(null);}}

说明:cglib生成代理是通过字节码生成的子类作为代理类,因此不能对private final方法代理;


比较:

CGLib动态代理创建代理实例速度慢,但是运行速度快;JDK动态代理创建实例速度快,但是运行速度慢。如果实例是单例的,推荐使用CGLib方式动态代理,反之则使用JDK方式进行动态代理。Spring的实例默认是单例,所以这时候使用CGLib性能高。 


阅读全文
0 0