java_Proxy动态代理_AOP

java

讲了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

回到顶部