标签:
在上篇博客中个,咱们一起组建了一个容器,里面封装了业务,这样,咱们就将业务和服务的组装放到了客户端,而客户端就相当于咱们的开发中使用到的配置文件,大家发现问题了吗?就是我不能动态改动了?业务容器在代理完成后,重新添加一个容器,这时候,是不被允许的,那这个容器就是个编译时起作用的容器,他就丧失了很多的灵活性!
那怎么办呢?实际就是调换一下调用顺序就好,大家看看结果:
改造后类图
/**
* 打招呼动态代理类,给业务类添加功能
* 前一版本为JDK代理实现
* 本次添加执行方法之前打印到控制台‘befor’
* 本次添加执行方法之后打印到控制台‘after’
*本次版本为DGLIB代理
* 换代理类原因,JDK代理要求被代理类必须实现某接口,因为它底层实现是新建一个类,实现和被代理类相同的接口
* 用代理类新建的业务类代替原业务类
* CGLIB代理是新建一个类,继承自被代理类,用新建的代理类替换掉原业务类,就不需要接口了
*
*5.0版本增加服务组装容器,将服务从代理类中抽离出去了,我们的代理类成为了一个bean
*6.0将服务容器定义为接口
*7.0增加业务容器
*8.0 业务容器不灵活,将获取代理放置到业务容器端,实现动态增加元素,也能拿到代理
* @author 许恕
* @version 3.0.0 , 2015年6月16日 下午3:20:13
*/
public class CGLibDynamicProxy implements MethodInterceptor {
//服务类容器
private IProxyMehds proxyMehds;
//代理工厂类:单例模式,优化内存开销
private static CGLibDynamicProxy instance = new CGLibDynamicProxy();
//构造函数
private CGLibDynamicProxy() {
}
//获取cglib代理工厂类
public static CGLibDynamicProxy getInstance() {
return instance;
}
/**
* 使用代理工厂生成某个类的代理
*
* @param cls 要代理的类
* @return 返回已经代理好的类
*/
@SuppressWarnings("unchecked")
public <T> T getProxy(Class<T> cls) {
return (T) Enhancer.create(cls, this);
}
//重写被代理对象的方法执行
//所有的方法执行,到反射的级别都是invoke,重写了这个方法,就重写了所有的方法执行,实现了代理
@Override
public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
//重要改进:从服务容器中执行方法,不再是写死的!
proxyMehds.beforeBean();
//方法正常执行的语句
Object result = proxy.invokeSuper(target, args);
//重要改进:从服务容器中执行方法,不再是写死的!
proxyMehds.afterBean();
return result;
}
//服务容器的get方法
public IProxyMehds getProxyMehds() {
return proxyMehds;
}
//服务容器的set方法
public void setProxyMehds(IProxyMehds proxyMehds) {
this.proxyMehds = proxyMehds;
}
}
/**
* 业务类容器:
* 用map盛放要切入服务的业务类
*
* @author 许恕
* @version 3.0.0 , 2015-6-29 14:25:21
*/
public class DoMehds implements IDoMehds {
//盛放执行业务的map
private HashMap<String,Object> DoBeans;
//代理类
private CGLibDynamicProxy proxy ;
/**
* 封装获取元素的方法,每次获取元素都封装一个代理
*
* @param 元素的名字
* @return 代理好的元素
*/
public Object getBean(String beanName){
return proxy.getProxy(DoBeans.get(beanName).getClass());
}
//获取业务map
public HashMap<String, Object> getDoBeans() {
return DoBeans;
}
//设置业务map
public void setDoBeans(HashMap<String, Object> doBeans) {
DoBeans = doBeans;
}
//获取代理类
public CGLibDynamicProxy getProxy() {
return proxy;
}
//设置代理类
public void setProxy(CGLibDynamicProxy proxy) {
this.proxy = proxy;
}
}
/**
* 执行代理程序的客户端
*
* @author 许恕
* @version 3.0.0 , 2015年6月16日 下午3:18:42
*/
public class Client {
//客户端执行的主方法:系统规定
public static void main(String[] args) {
//盛放方法执行前的对象的容器
HashMap<String,Object> beforBeans;
HashMap<String,Object> afterBeans;
//配制方法执行前要执行哪些方法
HashMap<String,String> beforMethods;
HashMap<String,String> afterMethods;
//实例以上定义的服务类map
beforMethods=new HashMap();
beforBeans=new HashMap();
afterMethods=new HashMap();
afterBeans=new HashMap();
//将服务类AspectClass1添加到方法执行要加载的服务类
beforBeans.put("AspectClass1", new AspectClass1());
beforBeans.put("AspectClass2", new AspectClass2());
afterBeans.put("AspectClass3", new AspectClass3());
afterBeans.put("AspectClass4", new AspectClass4());
//规定每个服务类要执行的方法
beforMethods.put("AspectClass1", "SayHello");
beforMethods.put("AspectClass2", "SayGoodBye");
afterMethods.put("AspectClass3", "SayHi");
afterMethods.put("AspectClass4", "Eat");
//实例服务类容器,将四个map传入容器中
ProxyMehds proxyMehds =new ProxyMehds();
proxyMehds.setBeforBeans(beforBeans);
proxyMehds.setBeforMethods(beforMethods);
proxyMehds.setAfterBeans(afterBeans);
proxyMehds.setAfterMethods(afterMethods);
//实例业务map
HashMap<String,Object> DoBeansMap = new HashMap<String,Object> ();
//将业务装载到map中
DoBeansMap.put("dobeans1", new GreetingImpl());
DoBeansMap.put("dobeans2", new EatClass());
//将业务map装载到容器中
DoMehds doMehds = new DoMehds();
doMehds.setDoBeans(DoBeansMap);
//实例代理类
CGLibDynamicProxy cglib =CGLibDynamicProxy.getInstance();
//接受切面
cglib.setProxyMehds(proxyMehds);
doMehds.setProxy(cglib);
//接受要代理的对象
Greeting greeting = (Greeting)doMehds.getBean("dobeans1");
EatClass eatObject = (EatClass)doMehds.getBean("dobeans2");
//执行对象的某个方法
greeting.sayHello("Jack");
eatObject.Eat();
}
}
代码的灵活,就像生活一般,在代码灵活的过程中,我们就会对比下生活,生活中,我们每个人,事,物都是独立的对象,而在生活中的时间轴中,我们也是过程化的组织,我们的代码和生活,在思想上都是相同的,优化的不仅仅是代码,还有思想啊!
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/xvshu/article/details/46689237