静态代理与动态代理模式

1.静态代理模式

  • 静态代理角色分析

    抽象角色:一般由接口或抽象类来实现

    真实角色:实现抽象角色的实现类,也是被代理的角色

    代理角色:代理真是角色,一般会做一些附属操作,比如记录日志等

    客户:使用代理角色进行一下操作

  • 抽象角色

    public interface UserService {
    
        void add();
    
        void update();
    
        void query();
    
        void delete();
    
    }
    
  • 真实角色

    public class UserServiceImpl implements UserService{
    
        @Override
        public void add() {
            System.out.println("添加了一个用户!");
        }
        @Override
        public void update() {
            System.out.println("修改了一个用户!");
        }
        @Override
        public void query() {
            System.out.println("查询了一个用户!");
        }
        @Override
        public void delete() {
            System.out.println("删除了一个用户!");
        }
    }
    
  • 代理角色

    public class UserServicePoxy implements UserService {
    
        private UserService userService;
    
        public void setUserService(UserService userService) {
            this.userService = userService;
        }
        @Override
        public void add() {
            userService.add();
            addLog("添加");
        }
        @Override
        public void update() {
            userService.update();
            addLog("修改");
        }
        @Override
        public void query() {
            userService.query();
            addLog("查询");
        }
        @Override
        public void delete() {
            userService.delete();
            addLog("删除");
        }
        public void addLog(String methodName){
            System.out.println("【日志】"+methodName+"一个用户!");
        }
    }
    
  • 客户

    public class MyTest {
    
        public static void main(String[] args) {
            //创建真实对象
            UserService userService = new UserServiceImpl();
            //创建代理
            UserServicePoxy userServicePoxy = new UserServicePoxy();
            //将真实对象交给代理
            userServicePoxy.setUserService(userService);
            //用代理去添加用户
            userServicePoxy.add();
        }
    
    }
    

2.动态代理模式

​ 动态代理的角色与静态代理一样,只不过动态代理的代理类是动态生成的。动态代理分为基于接口的动态代理和基于类的动态代理。

- 基于接口的动态代理—JDK动态代理;

- 基于类的动态代理—cglib;

- 现在用的比较多的是用javasist来生成动态代理。

​ JDK动态代理需要了解两个类InvocationHandler和Proxy。

InvocationHander[程序处理]

​ 其invoke方法是代理角色在调用真实角色的处理方法时,会调用该方法,并用反射的方式实现真实角色的方法。

Proxy 代理

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

生成代理角色,loader 类加载器,interfaces 抽象角色的class对象集合,h 处理程序的实体类

  • 抽象角色
public interface UserService {
    void add();
    void update();
    void query();
    void delete();
}
  • 真实角色

    public class UserServiceImpl implements UserService {
        @Override
        public void add() {
            System.out.println("添加了一个用户!");
        }
        @Override
        public void update() {
            System.out.println("修改了一个用户!");
        }
    
        @Override
        public void query() {
            System.out.println("查询了一个用户!");
        }
        @Override
        public void delete() {
            System.out.println("删除了一个用户!");
        }
    }
    
  • 动态代理处理程序

    /**
     * 代理实例的调用处理程序接口实现类
     */
    public class ProxyInvocationHandler implements InvocationHandler {
        private Object target;
        public void setTarget(Object target) {
            this.target = target;
        }
        //代理角色调用真实角色中的方法时会调用invoke方法来实现真实角色中的方法(反射的思想)
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            log(method.getName());
            Object result = method.invoke(target,args);
            return result;
        }
    
        //生成代理类
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
        }
        void log(String msg){
            System.out.println("执行了"+msg+"方法!");
        }
    }
    
  • 客户端

    public static void main(String[] args) {
        //创建真实角色
        UserService userService = new UserServiceImpl();
        //创建处理程序
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //将真实角色注入到处理程序中,为代理做准备
        pih.setTarget(userService);
        //生成代理类
        UserService proxy = (UserService) pih.getProxy();
        //执行添加方法 其实是通过处理程序中的invoke调用真实角色中的add方法
        proxy.add();
    }
    
  • 执行结果

image-20210121160527521

posted @ 2021-01-21 16:10  随风mc  阅读(77)  评论(0)    收藏  举报