zoukankan      html  css  js  c++  java
  • java_Proxy动态代理_AOP

    讲了JDK里使用Proxy动态代理的机制,详细过程。

    切面类TransactionHandler需要实现InvocationHaandler接口,实现它的invoke方法。

    项目目录:

    User类代码:

    package com.oracle.model;
    
    public class User {
    
        private String name;
        private int age;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    }
    View Code

    UserDAO代码:

    package com.oracle.dao;
    
    import com.oracle.model.User;
    
    public interface UserDAO {
    
        void addUser(User u);
        void deleteUser(User u);
        
    }
    View Code

    UserService代码:

    package com.oracle.service.impl;
    
    import com.oracle.dao.UserDAO;
    import com.oracle.model.User;
    import com.oracle.service.UserService;
    
    
    public class UserServiceImpl implements UserService{
    
        //组合UserDAO
        private  UserDAO  userDAO;
    
        //调用的都是UserDAO的方法
        public UserServiceImpl(UserDAO userDAO) {
            super();
            this.userDAO = userDAO;
        }
    
        @Override
        public void addUser(User u) {
            this.userDAO.addUser(u);
            
        }
    
        @Override
        public void deleteUser(User u) {
            this.userDAO.deleteUser(u);
            
        }
    
    }
    View Code

    UserServiceImpl代码:

    package com.oracle.service.impl;
    
    import com.oracle.dao.UserDAO;
    import com.oracle.model.User;
    import com.oracle.service.UserService;
    
    
    public class UserServiceImpl implements UserService{
    
        private  UserDAO  userDAO;
        
        
    
        public UserServiceImpl(UserDAO userDAO) {
            super();
            this.userDAO = userDAO;
        }
    
        @Override
        public void addUser(User u) {
            this.userDAO.addUser(u);
            
        }
    
        @Override
        public void deleteUser(User u) {
            this.userDAO.deleteUser(u);
            
        }
    
    }
    View Code

    UserDAOImpl代码

    package com.oracle.dao.impl;
    
    import com.oracle.dao.UserDAO;
    import com.oracle.model.User;
    
    public class UserDAOImpl implements UserDAO{
    
        @Override
        public void addUser(User u) {
            System.out.println("a user added !");
            
        }
    
        @Override
        public void deleteUser(User u) {
            System.out.println("a user deleted !");
            
        }
    
    }
    View Code

    UserAction代码:

    package com.oracle.action;
    
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    import com.oracle.dao.UserDAO;
    import com.oracle.dao.impl.UserDAOImpl;
    import com.oracle.model.User;
    import com.oracle.service.UserService;
    import com.oracle.service.impl.UserServiceImpl;
    
    public class UserAction {
    
        
        public static void main(String[] args) {
            
            //被代理对象
            UserDAO  userDAO = new UserDAOImpl();
            
            //InvocationHandler
            TransactionHandler  handler = new TransactionHandler(userDAO);
            
            /**
             * 返回代理对象:$Proxy0 
             * Proxy.newProxyInstance三个参数:
             * 1,要用哪个ClassLoader来产生代理对象。
             *     它和被代理对象使用同一个ClassLoader,因为产生的代理对象里包含了一个被代理对象。
             * 2,产生的被代理对象实现了哪些个接口:接口里有哪些方法,生成的代理就有哪些方法
             *  new Class[]{UserDAO.Class}多个接口时,或userDAO.getClass().getInterfaces()
             * 3,当产生代理之后,当调用代理里面方法的时候,用哪一个Handler进行处理
             */
            UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(   
                    userDAO.getClass().getClassLoader(),    
                    userDAO.getClass().getInterfaces(),     
                    handler);  
             
        
            
            /**
             * 代理对象的方法是怎么产生的?
             * 我们的代理对象userDAOproxy里的方法有:
             * 1,addUser(User u)
             * 2,deleteUser(User u)
             * 当代理对象里每一个方法被调用的时候,都会把它自身及参数、代理对象、传给InvocationHandler,
             * 也就是我们的TransactionHandler,调用他的invoke方法
             */
            
            /**
             * 内部机制:
             * Class  $Proxy0 implements UserDAO{
             *         addUser(User u){
             *             Method  m  = UserDAO.getClass.getMethod
             *             handler.invoke(this,m,u);
             *         }
             * 
             * }
             */
            
            //产生的是不是UserDAO?再看他有哪些方法
            //产生的类:$Proxy0  是实现了UserDAO接口了
            /*System.out.println(userDAOProxy.getClass().getName());
            System.out.println(userDAOProxy instanceof UserDAO);
            Method[]  methods = userDAOProxy.getClass().getMethods();
            for(Method  m: methods){
                System.out.println(m.getName());
            } */
            
            UserService  userService = new UserServiceImpl(userDAOProxy);
            User  u = new  User();
            u.setAge(20);
            u.setName("王彦");
            userService.addUser(u);
            userService.deleteUser(u);
            
            
        }
    }
    View Code

    TransactionHandler代码:

    package com.oracle.action;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    
    
    public class TransactionHandler implements InvocationHandler{
    
        private  Object  target;
        
        public TransactionHandler(Object target) {
            super();
            this.target =  target;
        }
    
        public Object getTarget() {
            return target;
        }
    
        public void setTarget(Object target) {
            this.target = target;
        }
        
        
    
        //处理业务逻辑可以传进去Method,进行名字判断,不同的方法做不同的逻辑处理
        public void beforeMethod(Method m){
            //if(m.getName().equals(anObject))....做不同处理
            System.out.println(m.getName()+" beginning...");
        }
        public void afterMethod(Method m){
            System.out.println(m.getName()+" ending...");
        }
        
        /**
         * 三个参数:1,代理对象 2,被调用方法,3,被调用方法的参数
         *    代理的哪个方法被掉用,就把代理对象、方法及参数传过来,
         *    首先加自己的业务逻辑,再调用被代理对象的方法
         */
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
        
            beforeMethod(method); 
            //调用被代理对象
            Object   obj = method.invoke(this.target,args);
            afterMethod(method);
            return obj;
        }
    
    }
    View Code

    运行结果:

    addUser beginning...
    a user added !
    addUser ending...
    deleteUser beginning...
    a user deleted !
    deleteUser ending...

    User的addUser、deleteUser方法前后都加上了想要处理的业务逻辑,而源代码不用改变。

    AOP用处:

    权限、日志、审查、效率检查、异常管理。。。

  • 相关阅读:
    保护模式下通过写显存在屏幕上输出字符串
    Linux0.01 引导代码分析-head.s
    OpenGL Super Bible 第四章 Transform 程序绘图部分代码解析
    Ubuntu10.04 下编译 OpenOffice DEV300 分支
    今天把博客开通了,欢迎来访!
    沟通的工具ER图
    为什么博客叫秋水?
    mysql.基础笔记
    如何阅读别人的C代码
    Github搜索与查看
  • 原文地址:https://www.cnblogs.com/lihaoyang/p/4874095.html
Copyright © 2011-2022 走看看