使用JDK中的InvocationHandler、Proxy实现动态代理

[align=center][b]动态代理(Dynamic Proxy)[/b][/align]
[b]一、切面编程(在方法前后加上一些逻辑,如下:在save(User user)方法前后加逻辑)[/b]
准备工作:
public class UserDAOImpl {
public void save(User user) {
System.out.println("user saved!");
}
}

[b]1、实现方法一:直接在方法里面逻辑前后进行添加[/b]
public class UserDAOImpl implements UserDAO {
public void save(User user) {
System.out.println("user start"); //在方法前添加逻辑
System.out.println("user saved!");
}
}

[b]2、实现方法二:使用继承进行添加[/b]
public class UserDAOImpl2 extends UserDAOImpl {
@Override
public void save(User user) {
System.out.println("user start"); //在方法前添加逻辑
super.save(user);
}
}

[b]3、实现方法三:使用接口进行添加[/b]
添加接口UserDAO
public interface UserDAO {
public void save(User user);
}

让UserDAOImpl继承接口
public class UserDAOImpl implements UserDAO {
public void save(User user) {
System.out.println("user saved!");
}
}

让UserDAOImpl2继承接口
public class UserDAOImpl2 implements UserDAO {

private UserDAOImpl userDAOImpl = new UserDAOImpl();

public void save(User user) {
System.out.println("user start"); //在方法前添加逻辑
userDAOImpl.save(user);
}
}

[b]小总结:三种方法中,使用接口和组合最为合适,但是如果要添加逻辑的方法十分多,而且因继承接口而形成的结构十分复杂的时候,可以使用动态代理来帮助实现。[/b]
[b]二、使用动态代理添加逻辑[/b]
将所需要添加的逻辑封装成一个类,让其继承InvocationHandler接口
public class LogInterceptor implements InvocationHandler {

private Object target; //需要添加逻辑的对象

public LogInterceptor(Object target) {
this.target = target;
}

public void log(Method m) {
System.out.println(m.getName() + " start");
}

/*
* proxy 代理对象
* method 代理对象要执行的方法
* args 所需执行方法的参数
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
log(method); //在执行方法前添加逻辑
method.invoke(target , args);
return null;
}

}

使用Proxy获得代理对象,代理对象与被代理对象要实现同样的接口
public class TestProxy {
/*
* userDAO 要代理的对象,实现了UserDAO接口
* li 给代理添加逻辑的类
* proxy 通过Proxy的静态方法生成的代理对象
* 代理对象与被代理的对象的ClassLoader要一样
* 通过传入的参数,实现与代理对象同样的接口
*/
public void testProxy() {
UserDAO userDAO = new UserDAOImpl();
LogInterceptor li = new LogInterceptor(userDAO);
UserDAO proxy = (UserDAO)Proxy.newProxyInstance(
userDAO.getClass().getClassLoader(), new Class[]{UserDAO.class}, li);
proxy.save(new User());
proxy.delete();
}
}

[img]http://dl.iteye.com/upload/attachment/0083/8991/dd4df795-9392-3e05-9064-8a6bc8a6fec5.jpg[/img]

你可能感兴趣的:(设计模式)