[码歌老薛]动态代理之多级代理实现方案以及细节分析
2018-12-19 本文已影响62人
坑王老薛
本内容均属码歌老薛原创,需要转载请注明出处:https://www.jianshu.com/p/29548a7b606f
对于本文章如果有疑问,请加老薛qq:1811112688
1-7-6 多级代理
业务分析实现业务场景:虾米吃海藻 小鱼吃虾米,大鱼吃小鱼
简单业务概述,当虾米吃海草时,小鱼一直在监视虾米有没有执行eat();方法,如果执行则小鱼执行eatSmallShrimp();大鱼执行eatLitteFish();将小鱼吃掉。
1-7-6 需求分析第一步
i:主要业务和次要业务的分析,这里吃为主要业务,当虾米吃了海藻,意味着小鱼一直在监听虾米吃的动作,如果虾米吃的动作一旦完成,或者被调用,意味着小鱼就要准备出场,将虾米干掉。
ii:根据上面的分析也就意味着小鱼应该是一个Agent对象,里面存储了次要业务,吃小虾米。
1-7-7 编写方式
1: 创建主要业务接口
2:创建虾米对象且实现主要业务接口
3:创建实现处理器类
4:编写代理工厂,代理对象通过工厂创建出来
5:编写测试类
1-7-8 测试用例
主要业务接口
/**
* 编写主要核心业务逻辑
*/
public interface Service {
void eat();
}
虾米类实现主要业务接口
public class SmallShrimp implements Service {
@Override
public void eat() {
System.out.println("虾米吃海藻");
}
}
代理工厂
public class ProxyFactory {
public static Service getInstance(Class<?> clz){
//创建真实角色
SmallShrimp shrimp = new SmallShrimp();
//获取代理角色 (实现了处理器接口的对象)
LittleFish fish = new LittleFish(shrimp);
//获取监听对象,查看真实角色是否执行了主要业务
Class[] clzArrays = {Service.class};
Service proxy = (Service) Proxy.newProxyInstance(clz.getClassLoader(),clzArrays,fish);
return proxy;
}
}
创建实现处理器类
public class LittleFish implements InvocationHandler {
//包装真实角色
private Service realObj;
public LittleFish(Service realObj) {
this.realObj = realObj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//监听虾米是否开始吃海藻了
method.invoke(realObj,args);
//准备让小鱼吃虾米
eatSS();
return null;
}
public void eatSS(){
System.out.println("小鱼准备吃虾米");
}
}
测试类
public class Test {
public static void main(String[] args) throws Exception {
Service service = ProxyFactory.getInstance(SmallShrimp.class);
service.eat();
}
}
结论
虾米吃海藻
小鱼准备吃虾米
1-7-9 需求分析第二步
i: 分析大鱼小鱼的业务场景,大鱼在监控小鱼,如果发现小鱼吃了虾米,
那么此时大鱼开始执行它吃小鱼的功能。这里有一个问题需要我们解决,
对于小鱼来说,它的主要业务好像应该是吃小鱼的方法eatSS();
这里要注意:
ii:因为整个业务场景中,其实是虾米吃海藻发生之后,
代理角色才被创建以及开始执行的。
1-7-7 编写方式
1:创建实现处理器类 代理实现类,大鱼类
4:编写代理工厂,代理对象通过工厂创建出来
5:编写测试类
1-7-8 编写方式
主要业务接口
/**
* 编写主要核心业务逻辑
*/
public interface Service {
void eat();
}
虾米类实现主要业务接口
public class SmallShrimp implements Service {
@Override
public void eat() {
System.out.println("虾米吃海藻");
}
}
代理工厂
public class ProxyFactory {
public static Service getInstance(Class<?> clz){
//创建真实角色
Service shrimp = new SmallShrimp();
//获取代理角色 (实现了处理器接口的对象)
InvocationHandler fish = new LittleFish(shrimp);
//获取监听对象,查看真实角色是否执行了主要业务
Class[] clzArrays = {Service.class};
Service proxy1 = (Service) Proxy.newProxyInstance(clz.getClassLoader(),clzArrays,fish);
//创建代理实现类对象
InvocationHandler bigFish = new BigFish(proxy1);
//这里获取监听对象 查看小鱼是否执行了吃虾米的操作,但是整个业务流程其实都是起始于小鱼除了虾米 所以这里负责
//查看的依旧是小鱼
Service proxy2 = (Service) Proxy.newProxyInstance(clz.getClassLoader(),clzArrays,bigFish);
return proxy2;
}
}
创建实现处理器类1
public class LittleFish implements InvocationHandler {
//包装真实角色
private Service realObj;
public LittleFish(Service realObj) {
this.realObj = realObj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//监听虾米是否开始吃海藻了
method.invoke(realObj,args);
//准备让小鱼吃虾米
eatSS();
return null;
}
public void eatSS(){
System.out.println("小鱼准备吃虾米");
}
}
创建实现处理器类2
public class BigFish implements InvocationHandler {
private Service proxy;
public BigFish(Service proxy) {
this.proxy = proxy;
}
@Override
public Object invoke(Object listener, Method method, Object[] args) throws Throwable {
/**
* 监听小鱼有没有吃虾米 如果吃了则准备吃小鱼 这里的问题是真实的执行对象是谁?
* 按照我们思路应该是小鱼,但是小鱼执行的是invoke方法,而该方法其实是通过监控执行的,而不是
* 主动调用的,这个方法的调用是由产生的代理对象执行的,所以这里我们执行该方法的对象应该是Proxy,
* 所以对于BigFish而言需要一个Proxy的引用
*/
method.invoke(proxy,args);
eatLF();
return null;
}
//辅助业务
public void eatLF(){
System.out.println("大鱼吃小鱼");
}
}
测试类
public class Test {
public static void main(String[] args) throws Exception {
Service service = ProxyFactory.getInstance(SmallShrimp.class);
service.eat();
}
}
结论
虾米吃海藻
小鱼准备吃虾米
大鱼吃小鱼