设计模式学习笔记:一、代理模式(动态代理步骤+举例)
代理模式实现步骤:
1.声明接口:注册需要被监听行为名称
2.接口实现类: 扮演被监控的类,负责被监听方法实现细节
3.InvocationHanler接口实现类:
1.次要业务/增强业务
2.将次要业务与被监听方法绑定执行
4.代理监控对象:
被监控类内存地址,被监控类实现的接口,
InvocationHandler实现类的实例对象
举例:
饭前便后要洗手
这里:主要业务是吃饭和上厕所,次要业务是洗手
1.声明接口,声明主要业务是吃饭和上厕所
public interface BaseService {
public void eat();
public void wc();
}
2.接口实现类,要实现吃饭和上厕所的实现类,这里拿person和dog做区分
public class Dog implements BaseService {
@Override
public void eat() {
System.out.println("啃骨头");
}
@Override
public void wc() {
System.out.println("三腿立");
}
}
public class Person implements BaseService {
@Override
public void eat() {//主要业务,代理模式要求开发人员只关心主要业务
System.out.println("使用筷子吃饭....");
}
@Override
public void wc() {
System.out.println("测试地球重力是否存在");
}
}
3.次要业务要实现InvocationHanler类,并重写invoke方法
public class Invaction implements InvocationHandler {
private BaseService obj;//具体被监控对象
public Invaction(BaseService param){
this.obj =param;
}
/*
*
* invoke方法:在被监控行为将要执行时,会被JVM拦截
* 被监控行为和行为实现方会被作为参数输送invoke
* ****通知JVM,这个被拦截方法是如何与当前次要业务方法绑定实现
* invoke方法三个参数
*
* int v= 小明.eat();//JVM拦截
* eat方法封装为Mehtod类型对象
* eat方法运行时接受所有的实参封装到Object[]
* 将负责监控小明的代理对象作为invoke方法第一个参数
*
*/
@Override
public Object invoke(Object porxy, Method method, Object[] params) throws Throwable {
//0.局部变量,接受主要业务方法执行完毕后返回值
Object value;
//1.确认当前被拦截行为
String methodName= method.getName();
//2.根据被拦截行为不同,决定主要业务和次要业务如何绑定执行
if("eat".equals(methodName)){//饭前要洗手
wash(); //洗手
value=method.invoke(this.obj, params); //吃饭
}else{//便后要洗手
value=method.invoke(this.obj, params);
wash();
}
return value; //返回被拦截方法,需要调用地方
}
//次要业务
public void wash(){
System.out.println("-----祈祷----");
}
}
4.创建代理监控对象:
public class ProxyFactory {
/*
*
* JDK动态代理模式下,代理对象的数据类型
* 应该由监控行为来描述
* 参数: Class文件,监控类
*/
public static BaseService Builder(Class classFile)throws Exception {
//1.创建被监控实例对象
BaseService obj= (BaseService) classFile.newInstance();
//2.创建一个通知对象
InvocationHandler adviser= new Invaction(obj);
//3.向JVM申请负责监控obj对象指定行为的监控对象(代理对象)
/*
* loader:被监控对象隶属的类文件在内存中真实地址
* interfaces:被监控对象隶属的类文件实现接口
* h:监控对象发现小明要执行被监控行为,应该有哪一个通知对象进行辅助
*/
BaseService $proxy= (BaseService) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), adviser);
return $proxy;
}
}
测试:
public static void main(String[] args) throws Exception {
//mike.eat();
//Person mike = new Person();
BaseService dog= ProxyFactory.Builder(Dog.class);
dog.eat();//专门负责监控mike的代理对象
BaseService mike= ProxyFactory.Builder(Person.class);
mike.eat();
}