外包公司 网站建设 上海,虚拟云主机wordpress,凡科 建设淘宝客网站,网站建设私活Spring的两种动态代理#xff1a;Jdk和Cglib 的区别和实现 
一、原理区别#xff1a; 
java动态代理是利用反射机制生成一个实现代理接口的匿名类#xff0c;在调用具体方法前调用InvokeHandler来处理。 
而cglib动态代理是利用asm开源包#xff0c;对代理对象类的class文件…Spring的两种动态代理Jdk和Cglib 的区别和实现 
一、原理区别 
java动态代理是利用反射机制生成一个实现代理接口的匿名类在调用具体方法前调用InvokeHandler来处理。 
而cglib动态代理是利用asm开源包对代理对象类的class文件加载进来通过修改其字节码生成子类来处理。 
1、如果目标对象实现了接口默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口可以强制使用CGLIB实现AOP 
3、如果目标对象没有实现了接口必须采用CGLIB库spring会自动在JDK动态代理和CGLIB之间转换 
如何强制使用CGLIB实现AOP 1添加CGLIB库SPRING_HOME/cglib/*.jar 2在spring配置文件中加入aop:aspectj-autoproxy proxy-target-class“true”/ 
JDK动态代理和CGLIB字节码生成的区别 1JDK动态代理只能对实现了接口的类生成代理而不能针对类 2CGLIB是针对类实现代理主要是对指定的类生成一个子类覆盖其中的方法 因为是继承所以该类或方法最好不要声明成final 
二、代码实现 
用户管理接口 
package com.lf.shejimoshi.proxy.entity;
//用户管理接口
public interface UserManager {//新增用户抽象方法void addUser(String userName,String password);//删除用户抽象方法void delUser(String userName);}用户管理接口实现类 
package com.lf.shejimoshi.proxy.entity;
//用户管理实现类,实现用户管理接口
public class UserManagerImpl implements UserManager{//重写新增用户方法Overridepublic void addUser(String userName, String password) {System.out.println(调用了新增的方法);System.out.println(传入参数为 userName: userName password: password);}//重写删除用户方法Overridepublic void delUser(String userName) {System.out.println(调用了删除的方法);System.out.println(传入参数为 userName: userName);}}JDK动态代理 
package com.lf.shejimoshi.proxy.jdk;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;import com.lf.shejimoshi.proxy.entity.UserManager;
import com.lf.shejimoshi.proxy.entity.UserManagerImpl;
//JDK动态代理实现InvocationHandler接口
public class JdkProxy implements InvocationHandler {private Object target ;//需要代理的目标对象Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(JDK动态代理监听开始);Object result  method.invoke(target, args);System.out.println(JDK动态代理监听结束);return result;}//定义获取代理对象方法private Object getJDKProxy(Object targetObject){//为目标对象target赋值this.target  targetObject;//JDK动态代理只能针对实现了接口的类进行代理newProxyInstance 函数所需参数就可看出return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);}public static void main(String[] args) {JdkProxy jdkProxy  new JdkProxy();//实例化JDKProxy对象UserManager user  (UserManager) jdkProxy.getJDKProxy(new UserManagerImpl());//获取代理对象user.addUser(admin, 123123);//执行新增方法}}JDK动态代理运行结果 Cglib动态代理需要导入两个jar包asm-5.2.jar,cglib-3.2.5.jar。版本自行选择 
package com.lf.shejimoshi.proxy.cglib;import java.lang.reflect.Method;import com.lf.shejimoshi.proxy.entity.UserManager;
import com.lf.shejimoshi.proxy.entity.UserManagerImpl;import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;//Cglib动态代理实现MethodInterceptor接口
public class CglibProxy implements MethodInterceptor {private Object target;//需要代理的目标对象//重写拦截方法Overridepublic Object intercept(Object obj, Method method, Object[] arr, MethodProxy proxy) throws Throwable {System.out.println(Cglib动态代理监听开始);Object invoke  method.invoke(target, arr);//方法执行参数target 目标对象 arr参数数组System.out.println(Cglib动态代理监听结束);return invoke;}//定义获取代理对象方法public Object getCglibProxy(Object objectTarget){//为目标对象target赋值this.target  objectTarget;Enhancer enhancer  new Enhancer();//设置父类,因为Cglib是针对指定的类生成一个子类所以需要指定父类enhancer.setSuperclass(objectTarget.getClass());enhancer.setCallback(this);// 设置回调 Object result  enhancer.create();//创建并返回代理对象return result;}public static void main(String[] args) {CglibProxy cglib  new CglibProxy();//实例化CglibProxy对象UserManager user   (UserManager) cglib.getCglibProxy(new UserManagerImpl());//获取代理对象user.delUser(admin);//执行删除方法}}Cglib动态代理运行结果 有什么问题可以留言讨论