标签:
讲了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; } }
UserDAO代码:
package com.oracle.dao; import com.oracle.model.User; public interface UserDAO { void addUser(User u); void deleteUser(User u); }
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); } }
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); } }
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 !"); } }
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); } }
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; } }
运行结果:
addUser beginning...
a user added !
addUser ending...
deleteUser beginning...
a user deleted !
deleteUser ending...
User的addUser、deleteUser方法前后都加上了想要处理的业务逻辑,而源代码不用改变。
AOP用处:
权限、日志、审查、效率检查、异常管理。。。
标签:
原文地址:http://www.cnblogs.com/lihaoyang/p/4874095.html