Java设计模式之代理模式
代理模式
应用场景
假设现在项目经理有一个需求:在项目现有所有类的方法前后打印日志。
如何在不修改已有代码的前提下,完成这个需求?
答案就是代理
静态代理
优点
- 可以使真实角色的操作更加纯粹!不用去关注一 些公共的业务
- 公共也就就交给代理角色!实现了业务的分工!
- 公共业务发生扩展的时候,方便集中管理!
缺点:
- 一个真实角色就会产生一个代理角色;代码量会翻倍,开发效率会变低
代码部分
创建Rent接口
package com.wuxin.damo01;
public interface Rent {
public void rent1();
public void rent2();
}
创建Rent接口的实现类
package com.wuxin.damo01;
public class Host implements Rent {
public void rent1() {
System.out.println("我想要出租一套四合院");
}
public void rent2() {
System.out.println("我想要出租一套空中阁楼");
}
}
创建代理对象
package com.wuxin.damo01;
public class Proxy implements Rent{
private Host host;
public Proxy(Host host) {
this.host = host;
}
public Proxy() {
}
public void rent1() {
host.rent1();
contract();
money();
}
public void rent2() {
host.rent2();
contract();
money();
}
public void contract() {
System.out.println("签租赁合同");
}
public void money() {
System.out.println("收租金");
}
}
创建测试对象
package com.wuxin.damo01;
public class Client {
public static void main(String[] args) {
Host host = new Host();
Proxy proxy = new Proxy(host);
proxy.rent1();
proxy.rent2();
}
}
日志
我想要出租一套四合院
签租赁合同
收租金
我想要出租一套空中阁楼
签租赁合同
收租金
Process finished with exit code 0
动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是我们直接写好的!
- 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
- 基于接口--- JDK动态代理[我们在这里使用]
- 基于类: cglib
- java字节码实现: javasist
总体来说,静态代理的优点他都有,静态代理的缺点他也避过了
需要了解两个类: Proxy:代理,InvocationHandler: 调用处理程序
代码部分
首先创建一个UserService接口
package com.wuxin.damo02;
public interface UserService {
public void add();
public void delete();
public void update();
public void query();
}
创建一个实现类去实现这个接口
package com.wuxin.damo02;
public class UserServiceImpl implements UserService{
public void add() {
System.out.println("新增一个用户");
}
public void delete() {
System.out.println("删除一个用户");
}
public void update() {
System.out.println("修改一个用户");
}
public void query() {
System.out.println("查询一个用户");
}
}
创建一个代理类(可作为工具类)
package com.wuxin.damo02;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(target, args);
return result;
}
public void log(String msg){
System.out.println("[日志]:执行了" + msg + "方法");
}
}
创建一个用户去测试代理
package com.wuxin.damo02;
public class Client{
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setTarget(userService);
UserService proxy = (UserService) pih.getProxy();
proxy.add();
}
}
日志输出:
[日志]:执行了add方法
新增一个用户
Process finished with exit code 0
苟利国家生死以,岂因祸福避趋之