代理模式的学习
1.代理模式的定义
代理模式是让一个中介对象代替别的所有对象去完成一项或多项共同的事项,并且还能附加一些中介特有的事项功能。通常代理类虽然具备更多的中介特有的事项功能,但是都是比较固定的。比如在JDBC中或各个框架里,都会存在事务的开启和提交等功能,如果我们直接将事务代码和业务代码写在一起,这样做会使得每一个需要事务的方法都要添加事务代码,造成代码的分散冗余。这时针对这种情况,我们就希望将业务代码和这些公共事项功能分离开来,使得每个业务方法都只写业务内容,同时在执行业务方法时自动添加这些公共事项功能。也就是抽离出来的业务代码是一个委托类,而可以将委托类自动增强并添加公共事项代码的公共类是一个代理类,它可以代理执行委托类并且具备了委托类原有的业务能力之余,增加了事务处理的代码。
2.代理模式的应用
springAOP的底层就是应用的代理模式、java中有静态代理、JDK动态代理等
3.代理模式的分类
代理模式作为23种经典设计模式之一,他是为其他对象提供一种代理以控制对这个对象的访问,主要分为静态代理和动态代理两种。
3.1 静态代理
静态代理是在程序运行之前,提前设置好代理类和委托类的关系以及相应的方法。
一般步骤是:先设置一个公共接口,一个代理类,一个委托类,其中代理类和委托类都需要实现这个公共接口,并且代理类需要将委托类设置为他的成员变量、以及相应的代理方法用于交互。
举个例子:
3.1.1 设置公共接口,设置公共事项功能。
package com.test;
public interface DoSomething{
public void doSomething();
}
3.1.2 设置委托类,需要功能的用户
package com.test;
public class User implements DoSometing {
public void doSometing () {
System.out.println("我想买些东西");
}
}
3.1.3 设置代理类,帮助用户实现功能的中介,可以帮助用户实现功能,也可以有一些自己特有的功能。
package com.test;
public class Proxy implements DoSomething{
private User user;
public Proxy() {
}
public Proxy(User user) {
this.user= user;
}
public void doSomething() {
pay();
buy();
user.doSomething();
}
public void pay(){
System.out.println("代缴费。。。");
}
public void buy(){
System.out.println("代买东西。。。");
}
}
3.1.4 实际使用场景,创建委托类,委托类可以通过通过代理类为中介去代理处理一些事情。
package com.test;
public class Client {
public static void main(String[] args) {
User user = new User();
Proxy proxy = new Proxy(user );
proxy.doSomething();
}
}
3.1.5 静态代理的优缺点
3.1.5.1 优点:
使实际使用者的操作更加纯粹,不用去关注一些公共的业务,只用专心处理本身的业务;将公共业务交给代理类处理,实现解耦;在对公共业务发生拓展或者修改的时候方便集中管理。
3.1.5.2 缺点:
由于需要对每个实际使用者都设置他的代理类等相关部分,会造成代码量翻倍和开发效率变低。
3.2 动态代理
动态代理就是可以动态的切换实际使用者, 通过一个代理类应对一堆不确定的实际使用者。
3.2.1 动态代理与静态代理的不同
3.2.1.1 动态代理和静态代理的角色一样,都是形式中介这个角色的职能。
3.2.1.2 动态代理的代理类是动态生成的,不需要手动去单独对应实际使用者去设置
3.2.1.3 动态代理分为两大类:基于接口的动态代理(比如:JDK的动态代理)和基于类(比如:cglib)的动态代理。
3.2.1.4 InvocationHandler接口
每一个动态代理类的调用处理程序都必须实现InvocationHandler接口
public Object invoke(Object proxy, Method method, Object[] args);
其中:
proxy: 代理类代理的代理对象
method: 我们所要调用某个对象的方法
args: 代理对象方法传递的参数
3.2.1.5 Proxy类
Proxy类的newProxyInstance方法,需要三个参数:被代理类的类加载器、被代理类实现的接口、invocationHandler的实现类用于动态生成代理对象,再通过代理对象调用方法执行
public static Object newProxyInstance(
ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h
) throws IllegalArgumentException;
- 点赞
- 收藏
- 关注作者
评论(0)