代理模式(Proxy):代理模式其实就是多一个代理类出来,替原对象进行一些操作。比如咱有的时候打官司需要请律师,因为律师在法律方面有专长,可以替咱进行操作表达咱的想法,这就是代理的意思。代理模式分为两类:1、静态代理(不使用jdk里面的方法);2、动态代理(使用jdk里面的InvocationHandler和Proxy)。下面请看示例:
##一、静态代理
### 1、uml建模:
![](https://box.kancloud.cn/2016-02-19_56c7196e4bf51.jpg)
##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();
}
}
/**
* 客户端测试类
*
* @author Leo
*/
public class Test {
public static void main(String[] args) {
/**
* 创建代理对象
*/
Targetable proxy = new Proxy();
/**
* 执行代理方法
*/
proxy.targetMethod();
}
}
~~~
##二、动态代理
### 1、uml建模:
![](https://box.kancloud.cn/2016-02-19_56c7196e5b442.jpg)
### 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;
}
}
/**
* 客户端测试类
*
* @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、可以将功能划分的更加清晰,有助于后期维护。
- 前言
- (一)策略模式建模与实现
- (二)观察者模式建模与实现
- (三)装饰者模式建模与实现
- (四)工厂方法模式建模与实现
- (五)抽象工厂模式建模与实现
- (六)单例模式建模与实现
- (七)命令模式建模与实现
- (八)适配器模式建模与实现
- (九)外观模式建模与实现
- (十)模板方法模式建模与实现
- (十一)迭代器模式建模与实现
- (十二)组合模式建模与实现
- (十三)状态模式建模与实现
- (十四)代理模式建模与实现
- (十五)建造者模式建模与实现
- (十六)原型模式建模与实现
- (十七)桥接模式建模与实现
- (十八)责任链模式建模与实现
- (十九)备忘录模式建模与实现
- (二十)解释器模式建模与实现
- (二十一)享元模式建模与实现
- (二十二)中介者模式建模与实现
- (二十三)访问者模式建模与实现
- Java设计模式博客全目录