为什么要学习代理模式?

因为AOP的底层机制就是动态代理!

代理模式:
- 静态代理
- 动态代理


静态代理


静态代理角色分析
抽象角色 : 一般使用接口或者抽象类来实现 【租房这件事】

真实角色 : 被代理的角色 【房东】

代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作 .【中介】

客户 : 使用代理角色来进行一些操作 .【需要租房的人】
静态代理的好处:
可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .

公共的业务由代理来完成 . 实现了业务的分工 ,

公共业务发生扩展时变得更加集中和方便 .
缺点 :
类多了 , 多了代理类 , 工作量变大了 . 开发效率降低 .代码量会翻倍,开发效率会变低。
静态代理的例子一:代码实现:

Rent . java 即抽象角色

//租房
public interface Rent {
public void rent();
}

Host . java 即真实角色

public class Host implements Rent{

public void rent() {
System.out.println("房东要出租房子");
}
}

Proxy . java 即代理角色

public class Proxy implements Rent{
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void rent() {
host.rent();
seeHouse();
hetong();
fare();
}
//看房
public void seeHouse(){
System.out.println("中介带你看房");
}
//收中介费
public void fare(){
System.out.println("收中介费");
}
//合同
public void hetong(){
System.out.println("签合同");
}
}

Client . java 即客户

public class Proxy implements Rent{
private Host host;

public Proxy() {
}

public Proxy(Host host) {
this.host = host;
}

public void rent() {
host.rent();
seeHouse();
hetong();
fare();
}


//看房
public void seeHouse(){
System.out.println("中介带你看房");
}

//收中介费
public void fare(){
System.out.println("收中介费");
}

//合同
public void hetong(){
System.out.println("签合同");
}

}
静态代理的例子二:

原有的实现功能:

【Spring】静态、动态代理模式_System


现在有需求,想在每个方法中加一个日志功能,但要遵循不改变原有代码的原则。

新增一个proxy代理类,

【Spring】静态、动态代理模式_java_02


最后在测试类中有如下改变:

【Spring】静态、动态代理模式_动态代理_03


深入理解图片:

【Spring】静态、动态代理模式_System_04


动态代理


  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的,不是我们直接写好的!
  • 动态代理分为两大类:
  • 基于接口的动态代理:JDK动态代理
  • 基于类的动态代理:cglib
  • 现在用的比较多的是 javasist 来生成动态代理 . 百度一下javasist

代码模板:
ProxyInvocationHandler.java

//等会我们会用这个类,自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object target;

public void setTarget(Object target) {
this.target = target;
}

public ProxyInvocationHandler(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+"方法");
}

}

Client.java

public class Client {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
//代理角色:不存在
ProxyInvocationHandler pih = new ProxyInvocationHandler(userService);
pih.setTarget(userService);//设置要代理的对象
//动态生成代理类
UserService proxy= (UserService) pih.getProxy();
proxy.add();
}
}