转载请注明出处:http://blog.****.net/lhy_ycu/article/details/39856435
代理模式(Proxy):代理模式事实上就是多一个代理类出来,替原对象进行一些操作。比方咱有的时候打官司须要请律师,由于律师在法律方面有专长,能够替咱进行操作表达咱的想法,这就是代理的意思。代理模式分为两类:1、静态代理(不使用jdk里面的方法);2、动态代理(使用jdk里面的InvocationHandler和Proxy)。以下请看演示样例:
一、静态代理
1、uml建模:
2、代码实现
/**
* 演示样例(一):代理模式 --静态代理(没有调用JDK里面的方法)
*
* 目标接口
*/ interface Targetable {
public void targetMethod();
} class Target implements Targetable { @Override
public void targetMethod() {
System.out.println("this is a target method...");
}
} class Proxy implements Targetable {
private Target target; public Proxy() {
this.target = new Target();
} private void beforeMethod() {
System.out.println("this is a method before proxy...");
} private void afterMethod() {
System.out.println("this is a method after proxy...");
} /**
* 在运行目标方法前后加了逻辑
*/
@Override
public void targetMethod() {
beforeMethod();
target.targetMethod();
afterMethod();
}
} /**
* client測试类
*
* @author Leo
*/
public class Test {
public static void main(String[] args) {
/**
* 创建代理对象
*/
Targetable proxy = new Proxy();
/**
* 运行代理方法
*/
proxy.targetMethod();
}
}
二、动态代理
1、uml建模:
2、代码实现
/**
* 演示样例(二):代理模式 --动态代理
*
* 以加入用户为例
*/
class User {
private String username;
private String password; public User() {
} public User(String username, String password) {
this.username = username;
this.password = password;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} @Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
} /**
* 目标接口
*/
interface IUserDao {
public void add(User user);
} class UserDaoImpl implements IUserDao {
@Override
public void add(User user) {
System.out.println("add a user successfully...");
}
} /**
* 日志类 --> 待织入的Log类
*/
class LogEmbed implements InvocationHandler {
private IUserDao target; /**
* 对target进行封装
*/
public IUserDao getTarget() {
return target;
} public void setTarget(IUserDao target) {
this.target = target;
} private void beforeMethod() {
System.out.println("add start...");
} private void afterMethod() {
System.out.println("add end...");
} /**
* 这里用到了反射
*
* proxy 代理对象
*
* method 目标方法
*
* args 目标方法里面參数列表
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
beforeMethod();
// 回调目标对象的方法
method.invoke(target, args);
System.out.println("LogEmbed --invoke-> method = " + method.getName());
afterMethod();
return null;
}
} /**
* client測试类
*
* @author Leo
*/
public class Test {
public static void main(String[] args) {
IUserDao userDao = new UserDaoImpl();
LogEmbed log = new LogEmbed();
log.setTarget(userDao);
/**
* 依据实现的接口产生代理
*/
IUserDao userDaoProxy = (IUserDao) Proxy.newProxyInstance(userDao
.getClass().getClassLoader(), userDao.getClass()
.getInterfaces(), log);
/**
* 注意:这里在调用IUserDao接口里的add方法时,
* 代理对象会帮我们调用实现了InvocationHandler接口的LogEmbed类的invoke方法。
*
* 这样做,是不是有点像Spring里面的拦截器呢?
*/
userDaoProxy.add(new User("张三", "123"));
}
}
三、总结
代理模式优点:1、一个代理类调用原有的方法,且对产生的结果进行控制。2、能够将功能划分的更加清晰,有助于后期维护。