• Java反射机制动态代理


    1.什么事反射机制动态代理

    在一段代码的前后动态执行其他操作,比如有一个方法是往数据库添加一个记录,我们可以通过动态代理,在操作数据库方法的前和后添加代码执行打开数据库连接和关闭数据库连接。

    2.演示

    学生管理类StudentManager.Class有三个方法,功能是新增一个学生数据addStudent(),删除一个学生数据deleteStudent(),
    获取当前时间getPersenterTime(),我通过动态代理实现,在addStudent()和deleteStudent()方法中我们在方法体的开头动态代理执行打开数据库的操作,在方法体的结尾我们动态代理关闭数据库连接的操作。

    为这三个方法定义接口规范 StudentService

    public interface StudentService {
        public void addStudent(String username);
        public void deleteStudent(String username);
        public String getPersentTime();
    }
    

    StudentManager.Class如下

    public class StudentManager implements StudentService {
        /**
         * 新增学生数据
         *
         * @param username
         */
        public void addStudent(String username) {
            System.out.println("在数据库中插入一条学生纪律");
        }
    
        /**
         * 删除学生数据
         *
         * @param username
         */
        public void deleteStudent(String username) {
            System.out.println("在数据库中删除一条学生纪律");
        }
    
        /**
         * 返回服务器当前时间
         *
         * @return
         */
        public String getPersentTime() {
            return "2018-07-30 3:30";
        }
    }
    

    添加方法拦截器StudentListener

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class StudentListener implements InvocationHandler {
        //代表需要代理的方法名
        private String methodsName = "addStudent,deleteStudent";
    
        public StudentListener(StudentManager manager) {
            this.manager = manager;
        }
    
        private StudentManager manager;
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (methodsName.contains(method.getName())) {
                //需要动态代理
                System.out.println("打开数据库链接");
                method.invoke(manager, args);
                System.out.println("关闭数据库链接");
            } else if (method.getName().equals("getPersentTime")) {
                //不需要动态代理,直接反射执行方法
                return method.invoke(manager, null);
            }
            return null;
        }
    }
    

    Proxy.newProxyInstance() 实现调用,也可以封装一下返回接口代理类方便调用。

    import java.lang.reflect.Proxy;
    
    public class Main {
        public static void main(String[] args) {
            StudentManager studentManager = new StudentManager();
            Class clazz = studentManager.getClass();
            StudentListener listener = new StudentListener(studentManager);
    
            StudentService serviceProxy = (StudentService) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), listener);
            serviceProxy.addStudent("张三");
            System.out.println("------------------------");
            serviceProxy.deleteStudent("李四");
            System.out.println("------------------------");
            System.out.println("时间:" + serviceProxy.getPersentTime());
        }
    }
    

    输出结果如下:
    image.png

  • 相关阅读:
    Algorithm Gossip (37) 快速排序法 ( 一 )
    Algorithm Gossip (36) Heap排序法( 堆排序 )
    Algorithm Gossip (35) Shaker法
    Algorithm Gossip (34) 希尔排序
    AlgorithmGossip (33) 选择、插入、气泡排序
    Algorithm Gossip (32) 得分排行
    Algorithm Gossip (31) 数字拆解(dp问题)
    Algorithm Gossip (30) m元素集合的 n 个元素子集
    Algorithm Gossip (29) 产生可能的集合
    Algorithm Gossip (27) 排列组合
  • 原文地址:https://www.cnblogs.com/chenyangqi/p/9391467.html
Copyright © 2020-2023  润新知