【Spring】动态代理(基于接口JDK 基于类cglib)
静态代理
动态代理
动态代理有三个角色:
接口
真实角色
生成代理角色的角色
java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
下面我们通过一个示例来了解一下动态代理(JDK基于接口的)
接口代码
//接口 public interface Service { public void doSomething(); }
真实角色
/** * @Description:真实角色 * @Author: cckong * @Date: */ public class UserService implements Service{ @Override public void doSomething() { System.out.println("UserService Call doSomething"); } }
生成代理角色的类
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @Description:生成动态代理角色的类 * @Author: cckong * @Date: */ public class ProxyInvocationHandler implements InvocationHandler { private Object target; public void setTarget(Object target) { this.target=target; } public Object getProxy(){ return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("invoke Call"); Object result=method.invoke(target,args); return result; } }
测试代码
public class Mytest { public static void main(String[] args) { UserService userService=new UserService();//生成真实角色 ProxyInvocationHandler pih=new ProxyInvocationHandler();//声明“生成代理角色”的类 pih.setTarget(userService);//将真实角色传进生成类里 Service proxy= (Service) pih.getProxy();//根据刚才传进来的真实角色 由生成类生成一个代理实例 proxy.doSomething();//调用代理实例的方法(是接口的方法) } }
结果图
基于CGLIB的
package com.cglib; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import org.junit.Test; import java.lang.reflect.Method; /** * @Description: * @Author: cckong * @Date: */ public class ProxyCglib implements MethodInterceptor { public Object getProxy(Class target){ Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(target); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("调用前=========="); Object result=methodProxy.invokeSuper(o,objects); System.out.println("调用后=========="); return result; } } class mytest{ // @Test public static void main(String[] args) { ProxyCglib proxyCglib=new ProxyCglib(); UserService userService= (UserService) proxyCglib.getProxy(UserService.class); userService.add(); } }
package com.cglib; /** * @Description: * @Author: cckong * @Date: */ public class UserService { public void add() { System.out.println("添加一个用户"); } }