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用处:
权限、日志、审查、效率检查、异常管理。。。
欢迎关注个人公众号一起交流学习:
以上是 java_Proxy动态代理_AOP 的全部内容, 来源链接: utcz.com/z/390545.html