zoukankan      html  css  js  c++  java
  • 【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("添加一个用户");
        }
    }

  • 相关阅读:
    div 和 span的区别
    div 和 span的区别
    javascript类的定义及成员修改
    C# bho操作dom 同时带有隐藏工具栏功能,菜单栏
    javascript类的定义及成员修改
    数据库原理8个例子sql语句
    数据库原理8个例子sql语句
    C++的声明和定义的出别
    C++的声明和定义的出别
    Visual Studio 添加图标和版本
  • 原文地址:https://www.cnblogs.com/cckong/p/14381118.html
Copyright © 2011-2022 走看看