代理模式
-
需要的是代理者,被代理者,共性接口,测试类
-
比如A访问C。B有一个代理C,B把内容交代后,给了C,C作为代理,需要对A进行一些其他访问控制,判断,同时C也完整的执行了B的内容。因此A对C的访问实际上就是A间接的访问B
-
静态代理和动态代理
-
反射的应用:动态代理
-
在不改变接口的前提下,控制对象的访问
-
从封装的角度讲, 是为了解决类与类之间相互调用而由此导致的耦合关系
-
从复用角度讲,可以解决不同类调用一个复杂类时,仅仅因较小的改变而导致整个复杂类新建一个类,a-c1,b-c2
-
强调类之间的封装和某方面的复用
代理 Boss和秘书(静态代理)
Interface Person{
void speak();
}
//被代理者
class Boss implements person{
@Override
public void speak() {
System.out.println("Boss:今晚开会");
}
}
//代理者 中间人
class Agent implements Person{
private Boss boss;
public Agent(Boss boss){
this.boss = boss;
}
public static void agentSpeak(){
System.out.println("秘书:今晚开会");
}
@Override
public void speak() {
agentSpeak();
boss.speak();//boss对象调用自己的方法,这个speak是调用Boss的实现方法
}
}
//测试类
public class ProxyModel {
public static void main(String[] args) {
Agent agent = new Agent(new Boss());
agent.speak();//秘书说的话就是Boss说的话
}
}
动态代理(反射)
public class DynamicProxyMode {
public static void main(String[] args) {
Boss boss = new Boss();//来了一个需要被代理对象
Person proxyInstance = (Person) ProxyFactory.getProxyInstance(boss);//通过代理工厂,传入对象得到一个代理实例,是接口类型的
/**
* 当代理类的对象调用speak()时,会自动的调用invoke().
* 因为在代理工厂里,创建了MyInvocationHandler的bind方法,来和传进来的被代理类连接
* obj传到创建了MyInvocationHandler的bind()中,然后把这个MyInvocationHandler的对象传给proxy()
* proxy中最后一个参数类型就是InvocationHandler,而且InvocationHandler的invoke有返回值,因此返回了掉用的结果
* 因此间接的实现了代理对象调用方法
*/
// 接口类型的代理实例.被代理类的方法
/**
* 经过上面的创建代理过程后,该接口类型的代理对象已经可以调用继承了接口的代理类的方法了
*/
/**
* 调用speak()
*/
proxyInstance.speak();//代理实例去代理的输出被代理类的方法
proxyInstance.eat();
}
}
interface Person{
void speak();
void eat();
}
class Boss implements Person{
@Override
public void speak() {
System.out.println("今晚开会");
}
@Override
public void eat() {
System.out.println("我在吃");
}
}
/*
动态代理时需要解决的问题
- 1. 如何根据加载到内存中的被代理类,动态的创建一个代理类及对象
- 2. 当通过代理类中的对象调用方法时,如何动态的去调用被代理类中的同名方法
*/
//创建一个代理工厂,专门产生代理类
class ProxyFactory {
/**
* 调用此方法,获取代理一个代理对象,解决问题一
* @param obj 被代理类的对象
* @return 代理实例
*/
public static Object getProxyInstance(Object obj){//obj是被代理类的对象
MyInvocationHandler handler = new MyInvocationHandler();
handler.bind(obj);//作用:联系MyInvocationHandler类,去实现具体的代理过程
/**
* static Object newProxyInstance(ClassLoader loader, 类<?>[] interfaces, InvocationHandler h)
* 参数
* loader - 类加载器来定义代理类
* interfaces - 代理类实现的接口列表
* h - 调度方法调用的调用处理函数
*/
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handler);
}
}
//创建一个InvocationHandler的实现类,InvocationHandler是由代理实例的调用处理程序实现的接口
class MyInvocationHandler implements InvocationHandler {
private Object obj;//需要使用被代理类的对象赋值
/**
* 绑定被代理对象
* @param obj
*/
public void bind(Object obj){
this.obj = obj;
}
//重写InvocationHandler接口的invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
* Method相当于是超级类,它的对象调用Method的invoke
*/
Object returnValue = method.invoke(obj, args); //超级类,也就是相当于Object一样的超级东西,调用Methods的invoke方法
return returnValue;
}
}