静态代理
为什么要学习代理模式?因为这就是SpringAOP的底层!
代理模式的分类:
- 静态代理
- 动态代理
1、静态代理
角色分析:
- 抽象角色:一般会使用接口或抽象类来实现(租房操作)
- 真实角色:被代理的角色(房东)
- 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作(中介)
- 客户:使用代理角色来进行一些操作 (租房的人)
代理步骤:
-
接口
package com.edgar.demo01; // 抽象角色:租房 public interface Rent { void rent(); }
-
真实角色
package com.edgar.demo01; //真实角色: 房东,房东要出租房子 public class LangLord implements Rent{ @Override public void rent() { System.out.println("房东要出租房子!"); } }
-
代理角色
package com.edgar.demo01; //代理角色:中介 public class Proxy implements Rent { private LangLord langLord; public Proxy() { } public Proxy(LangLord langLord) { this.langLord = langLord; } @Override public void rent() { this.seeHouse(); this.langLord.rent(); this.signContract(); this.fare(); } // 看房 public void seeHouse(){ System.out.println("中介带你看房"); } // 签租赁合同 public void signContract(){ System.out.println("签租赁合同"); } // 收中介费 public void fare(){ System.out.println("收中介费"); } }
-
客户端访问代理角色
package com.edgar.demo01; //客户类,一般客户都会去找代理! public class Client { public static void main(String[] args) { // 房东要租房子 LangLord langLord = new LangLord(); // 代理,中介帮房东租房子,但是呢?代理角色一般会有一些附属操作! Proxy proxy = new Proxy(langLord); // 你不用面对房东,直接找中介租房即可! proxy.rent(); } }
-
输出结果
中介带你看房 房东要出租房子! 签租赁合同 收中介费
代理模式的好处:
- 可以使得我们的真实角色更加纯粹 !不再去关注一些公共的事情
- 公共的业务由代理来完成 !实现了业务的分工 !
- 公共业务发生扩展时,方便集中管理!
缺点:
- 类多了 , 多了代理类 , 工作量变大了!开发效率降低 ~
我们想要静态代理的好处,又不想要静态代理的缺点,所以 , 就有了动态代理 !
2、静态代理再理解
练习步骤:
1、创建一个抽象角色,比如咋们平时做的用户业务,抽象起来就是增删改查!
package com.edgar.demo02;
// 抽象角色:增删改查业务
public interface UserService {
void add();
void delete();
void update();
void query();
}
2、我们需要一个真实对象来完成这些增删改查操作
package com.edgar.demo02;
// 真实对象,完成增删改查操作的人
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加了一个用户");
}
@Override
public void delete() {
System.out.println("删除了一个用户");
}
@Override
public void update() {
System.out.println("修改了一个用户");
}
@Override
public void query() {
System.out.println("查询了一个用户");
}
}
3、需求来了,现在我们需要增加一个日志功能,怎么实现!
- 思路1 :在实现类上增加代码 【在公司,原有的业务代码能不动就不动,把程序搞崩了就不好了】
- 思路2:使用代理来做,能够不改变原来的业务情况下,实现此功能就是最好的了!
4、设置一个代理类来处理日志!代理角色
package com.edgar.demo02;
// 代理角色,在这里面增加日志的实现
public class UserServiceProxy implements UserService{
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public void add() {
this.log("add");
this.userService.add();
}
@Override
public void delete() {
this.log("delete");
this.userService.delete();
}
@Override
public void update() {
this.log("update");
this.userService.update();
}
@Override
public void query() {
this.log("query");
this.userService.query();
}
// 日志方法
public void log(String msg){
System.out.println("[debug] 使用了" + msg + "方法");
}
}
5、测试访问类:
package com.edgar.demo02;
public class Client {
public static void main(String[] args) {
// 真实角色
UserService userService = new UserServiceImpl();
// 使用代理类实现日志功能!
UserServiceProxy proxy = new UserServiceProxy();
proxy.setUserService(userService);
proxy.add();
}
}
OK,到了现在代理模式大家应该都没有什么问题了,重点大家需要理解其中的思想;
我们在不改变原来的代码的情况下,实现了对原有功能的增强,这是AOP中最核心的思想
聊聊AOP:纵向开发,横向开发