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用处:

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

原文地址:https://www.cnblogs.com/lihaoyang/p/4874095.html