java 代理

    技术2022-07-11  134

    github地址 : https://github.com/lishanglei/proxy.git

    静态代理

    静态代理在不改变目标对象的前提下,实现对目标对象功能的拓展

    不足:静态代理实现了目标对象的所有方法,一旦目标接口增加,代理对象和目标对象都要进行相应修改

    public class AdminServiceProxy implements AdminService { private AdminService adminService; public AdminServiceProxy(AdminService adminService) { this.adminService = adminService; } @Override public void update() { System.out.println("判断用户是否有权限进行更新操作"); adminService.update(); System.out.println("记录用户执行的更新操作"); } @Override public Object find() { System.out.println("判断用户是否有权限进行数据查询操作"); System.out.println("记录用户执行的数据查询操作"); return adminService.find(); } }
    动态代理

    代理对象不需要implements接口

    代理对象的生成利用JDK的api,在JVM内存中动态的构建Proxy对象,需要使用java.lang.refect.Proxy

    动态代理可以让我们在运行时动态生成代理类,解耦程度更高.java的动态代理实现主要是借助java.lang.reflect包中的Proxy类和InvocationHandler接口,所有对动态代理对象的方法调用都会转发到InvocationHandler中的invoke()方法中实现,一般我们称实现了InvocationHandler接口的类为调用处理器

    我们可以通过Proxy的静态工厂方法newProxyInstance创建动态代理类实例

    1.接口
    public interface Star { String sing(); String dance(); }
    2.实现类
    public class LiuDeHua implements Star { @Override public String sing() { System.out.println("在唱给我一杯忘情水"); return "唱完"; } @Override public String dance() { System.out.println("在跳开心的马骝"); return "跳完"; } }
    3.代理类
    @Data public class ObjectProxy implements InvocationHandler { //通用代理对象 //目标类,就是被代理对象 private Object target; public ObjectProxy(Object target) { this.target = target; } /** * @param proxy 代理对象 * @param method 调度方法 * @param args 调度方法参数 * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { proxy=target; //为代理对象赋值 System.out.println("收钱"); //代理增强 Object obj =method.invoke(proxy,args);//执行代理对象方法 return obj; } }
    4.使用工厂模式创建代理对象
    public class ProxyFactory { //生成代理类 public static Object createProxyObj(Object obj, InvocationHandler target){ return Proxy.newProxyInstance( obj.getClass().getClassLoader(), //被代理对象的类加载器 obj.getClass().getInterfaces(), //被代理对象的全部接口 target //调用处理器(代理对象) ); } }
    5.使用
    @Test public void test1(){ Star star =new LiuDeHua(); //被代理对象 ObjectProxy proxy =new ObjectProxy(star); //被代理对象增强方案 Object obj =ProxyFactory.createProxyObj(star,proxy);//创建动态代理对象 Star s =(Star)obj; //执行代理对象增强后的方法 s.dance(); }
    cglib

    通过“继承”可以继承父类所有的公开方法,然后可以重写这些方法,在重写时对这些方法增强,这就是cglib的思想

    1.目标类
    public class Dog { final public void run(String name) { System.out.println("狗"+name+"----run"); } public void eat() { System.out.println("狗----eat"); } }

    2.代理类

    public class MyMethodInterceptor implements MethodInterceptor { /** * * @param o 要进行增强的对象 * @param method 拦截的方法 * @param objects 参数列表:基本数据类型需要传入其包装类型 * @param methodProxy 对方法的代理,invokeSuper标识对被代理对象方法的调用 * @return * @throws Throwable */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy ) throws Throwable { System.out.println("这里对目标类进行加强"); //采用方法调用,而非反射 Object object = methodProxy.invokeSuper(o, objects); return object; } }

    3.测试类

    public class CglibProxyTest { public static void main(String[] args) { //在指定目录下生成动态代理类,我们可以反编译看一下里面的内容 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"D:\\java\\java_workspace"); //创建Enhancer对象,类似于JDK代理的proxy类,下一步设置几个参数 Enhancer enhancer =new Enhancer(); //设置目标类的字节码文件 enhancer.setSuperclass(Dog.class); //设置回调函数 enhancer.setCallback(new MyMethodInterceptor()); //这里的create()方法是真是的创建代理类 Dog proxyDog =(Dog)enhancer.create(); //调用代理类的eat方法 proxyDog.eat(); } }
    Processed: 0.011, SQL: 9