静态代理比较简单,是由程序员编写的代理类,并在程序运行前就编译好的,而不是由程序动态产生代理类,这就是所谓的静态。
特点:
1、程序员编写的代理类,并在程序运行前就编译
2、不是由程序动态生成代理类
3、目标对象和代理对象 都想需要实现相同接口
静态代理模式实现方式:
- 聚合
- 继承
CASE: 需求 用户登录操作前后增加打印日志
//1.抽象主题接口
public interface ClientUser {
String login(String username, String password);
}
//2.真实主题类
public class Manager implements ClientUser {
@Override
public String login(String username, String password) {
String message = String.format("login username[%s],password[%s]", username, password);
System.out.println(message);
return "SUCCESS";
}
}
聚合方式
以聚合方式实现的代理主题
public class ManagerProxy implements ClientUser{
private Manager manager;
public ManagerProxy(Manager manager) {
this.manager = manager;
}
@Override
public String login(String username, String password) {
System.out.println("Log:manger 登录操作开始");
String result = manager.login(username, password);
System.out.println("Log:manger 登录操作结束");
return result;
}
}
测试:
Manager manger= new Manager();
ClientUser cl= new ManagerProxy(manger);
cl.login("Darren","123456")
继承方式
以继承方式实现静态代理
public class ManagerProxy extends Manager {
@Override
public String login(String username, String password) {
System.out.println("Log:manger 登录操作开始");
String result = super.login(username, password);
System.out.println("Log:manger 登录操作结束");
return result;
}
}
测试
ManagerProxy proxy = new ManagerProxy();
proxy.login("Darren","123456")
优点
可以在不修改目标对象功能的前提下,能通过代理对象对目标功能扩展
缺点:
- 类爆炸
因为代理需要与目标对象实现相同的接口,所以会有很多代理类,类太多.(在静态代理中,被代理的类是固定的,一个代理类对应一个被代理类,就需要编写大量的代理类,比较繁琐。
- 维护难,变化影响大
一旦接口增加方法,目标对象与代理对象都要维护.。
静态代理问题分析:
在代码code阶段规定这种代理关系,代理类通过编译器编译成class文件。当系统运行时,此class已经存在了。
这种静态的代理模式固然在访问无法访问的资源,增强现有的接口业务功能方面有很大的优点,但是大量使用这种静态代理,会使系统内的类的规模增大,并且不易维护;
并且由于代理对象和目标对象的功能 本质上是相同的,代理对象只是起到了中介的作用,这种代理在系统中的存在,导致系统结构比较臃肿和松散。
解决方案: 动态代理
为了解决静态代理带来的问题,就有了动态地创建代理的想法,即:
在运行状态中,需要代理的地方,根据目标接口 和目标对象,动态地创建一个Proxy(代理对象),用完之后,就会销毁,这样就可以避免了代理角色的class在系统中冗杂的问题了。