zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    C# lock
    read appSettings in configuration file by XElement with xmlns
    get all sites under IIS
    Cross-site scripting(XSS)
    Do not throw System.Exception, System.SystemException, System.NullReferenceException, or System.IndexOutOfRangeException intentionally from your own source code
    C++ 算法
    C++ 数据结构概念
    C++ STL 常用算术和生成算法
    C++ STL 常用拷贝和替换算法
    C++ STL 常用排序算法
  • 原文地址:https://www.cnblogs.com/chenyangqi/p/9391467.html
Copyright © 2011-2022 走看看