代理模式
介绍
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
1. 组成
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
2. 分类
2.1. 静态代理
所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
2.2. 动态代理
实现阶段不用关心代理类,而在运行阶段才指定哪一个对象 ,并在内存中直接创建代理对象
3.静态代理演示
//抽象角色 接口
public interface Smoke{
public void buy();
}
//真实角色 目标对象
public class Parent implements Smoke{
@override
public void buy(){
System.out.println("爸爸的烟买好了");
}
}
//代理角色
public class Son implements Smoke{
private Smoke target;//多态调用
public Son(Smoke target){
this.target = target;
}
@Override
public void buy() {
// 在代理中通过目标来调用真实行为
target.buy();
}
}
4.动态代理演示
静态代理中,需要手动编码Son代理类(Proxy)来实现Smoke接口,而动态代理可以在程序运行时,内存自动创建实现Smoke接口的代理,无需定义Son类.
主要功能 : 日志记录 性能统计 安全控制 事务处理
- 改写买烟
- 目标对象
public class Parent implements Smoke{
@Override
public void buy() {
System.out.println("爸爸的烟买好了");
}
}
public interface Smoke {
public void buy();
}
//一个新的目标对象
public class Uncle implements Smoke{
@Override
public void buy() {
System.out.println("叔叔的烟买好了");
}
}
//目标对象Parent类及Smoke接口保留,Son代理类要实现InvocationHandler
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class Son implements InvocationHandler {
private Object smoke;
public ihandler(Object smoke){
this.smoke = smoke;
}
@Override
public Object invoke(Object proxy,Method method,Object[] args)
throws Throwable{
method.invoke(smoke, args);
return null;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class xiyan{
public static void main(String[] args) {
//创建目标
Parent parent = new Parent();
Uncle uncle = new Uncle();
InvocationHandler buy1 = new Son(parent);
InvocationHandler buy2 = new Son(uncle);
//使用newProxyInstance完成代理对象的创建
Smoke dynamicProxy1 =(Smoke) Proxy.newProxyInstance(Parent.class.getClassLoader(),
Parent.class.getInterfaces(), buy1);
Smoke dynamicProxy2 =(Smoke) Proxy.newProxyInstance(Uncle.class.getClassLoader(),
Uncle.class.getInterfaces(), buy2);
//代理完成
dynamicProxy1.buy();
dynamicProxy2.buy();
}