在上篇博客中,大家和我一起研究了AOP的基本实现,但是,也给大家遗留了很多问题,在这篇博客,咱们一起研究如何针对这些问题进行持续的优化,看看在咱们的手里,AOP会成长为一个什么样的东西!
回顾:
看看上篇博客中,咱们一起实现的AOP类图:
咱们看看在CGLIB类里的问题
<span style="font-size:18px;">public class CGLibDynamicProxy implements MethodInterceptor { private static CGLibDynamicProxy instance = new CGLibDynamicProxy(); private CGLibDynamicProxy() { } public static CGLibDynamicProxy getInstance() { return instance; } @SuppressWarnings("unchecked") public <T> T getProxy(Class<T> cls) { return (T) Enhancer.create(cls, this); } @Override public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable { before(); Object result = proxy.invokeSuper(target, args); after(); return result; } <span style="color:#ff6600;"> private void before() { System.out.println("Before"); } private void after() { System.out.println("After"); } </span> }</span>
1,扩展服务
这样我们的扩展就会变得困难,大家试想一下这个场景,我们写好的业务,需要增加一个功能,就要写一个代理类,功能的变化,也必须修改代码,这就给我们的代码维护带来了很大的负担!如果我们要第一次要扩展2个方法,写了代理,下一次扩展3个,写了代理,下一次扩展1个写了代理,下一次不想要第一次的第2个方法了,怎么办?的确,这样的维护,是我们不想看到的,所以,我们将扩展的公共服务放到了一个容器中,大家看类图:
1.1封装公共服务类:
<span style="font-size:18px;">public class ProxyMehds { //盛放方法执行前的对象的容器 private HashMap<String,Object> beforBeans; private HashMap<String,Object> afterBeans; //配制方法执行前要执行哪些方法 private HashMap<String,String> beforMethods; private HashMap<String,String> afterMethods; @Override public void beforeBean() { try{ for (HashMap.Entry<String, Object> entry : beforBeans.entrySet()) { String objectKey = entry.getKey(); Object objectValure = entry.getValue(); Method beforMehod = objectValure.getClass().getMethod(beforMethods.get(objectKey)); beforMehod.invoke(objectValure); } }catch(Exception ex){ ex.printStackTrace(); } //Method sAge = c.getMethod("setAge"); } @Override public void afterBean() { try{ for (HashMap.Entry<String, Object> entry : afterBeans.entrySet()) { String objectKey = entry.getKey(); Object objectValure = entry.getValue(); Method beforMehod = objectValure.getClass().getMethod(afterMethods.get(objectKey)); beforMehod.invoke(objectValure); } }catch(Exception ex){ ex.printStackTrace(); } } public HashMap<String, Object> getBeforBeans() { return beforBeans; } public void setBeforBeans(HashMap<String, Object> beforBeans) { this.beforBeans = beforBeans; } public HashMap<String, Object> getAfterBeans() { return afterBeans; } public void setAfterBeans(HashMap<String, Object> afterBeans) { this.afterBeans = afterBeans; } public HashMap<String, String> getBeforMethods() { return beforMethods; } public void setBeforMethods(HashMap<String, String> beforMethods) { this.beforMethods = beforMethods; } public HashMap<String, String> getAfterMethods() { return afterMethods; } public void setAfterMethods(HashMap<String, String> afterMethods) { this.afterMethods = afterMethods; } }</span>
1.2封装代理类:
<span style="font-size:18px;">public class CGLibDynamicProxy implements MethodInterceptor { private static CGLibDynamicProxy instance = new CGLibDynamicProxy(); private ProxyMehds proxyMehds; private CGLibDynamicProxy() { } public static CGLibDynamicProxy getInstance() { return instance; } @SuppressWarnings("unchecked") public <T> T getProxy(Class<T> cls) { return (T) Enhancer.create(cls, this); } @Override public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable { proxyMehds.beforeBean(); Object result = proxy.invokeSuper(target, args); proxyMehds.afterBean(); System.out.println(""); return result; } public ProxyMehds getProxyMehds() { return proxyMehds; } public void setProxyMehds(ProxyMehds proxyMehds) { this.proxyMehds = proxyMehds; } }</span>
1.3服务类:
<span style="font-size:18px;">public class AspectClass1 { public void SayHello(){ System.out.println("This is AspectClass1.SayHello!"); } }</span>
1.4客户端:
<span style="font-size:18px;">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; beforMethods=new HashMap(); beforBeans=new HashMap(); beforBeans.put("AspectClass1", new AspectClass1()); beforMethods.put("AspectClass1", "SayHello"); beforMethods.put("AspectClass2", "SayGoodBye"); afterMethods=new HashMap(); afterBeans=new HashMap(); afterBeans.put("AspectClass3", new AspectClass3()); afterBeans.put("AspectClass4", new AspectClass4()); afterMethods.put("AspectClass3", "SayHi"); afterMethods.put("AspectClass4", "Eat"); ProxyMehds proxyMehds =new ProxyMehds(); proxyMehds.setBeforBeans(beforBeans); proxyMehds.setBeforMethods(beforMethods); proxyMehds.setAfterBeans(afterBeans); proxyMehds.setAfterMethods(afterMethods); //实例代理类 CGLibDynamicProxy cglib =CGLibDynamicProxy.getInstance(); //接受切面 cglib.setProxyMehds(proxyMehds); //接受要代理的对象 Greeting greeting = cglib.getProxy(GreetingImpl.class); //执行对象的某个方法 greeting.sayHello("Jack"); } }</span>
总结:
这样封装之后的好处是什么呢,就是我们的服务不再固定,而是在代理中定义了一个空壳子,这样每次使用,都是复用的空壳子,也是我们常说的框架,而后期的服务类是后加入的,在客户端动态初始化制定的,这样我们的扩展就变得方便,写好一个类,我们就可以直接配置下xml(类似于客户端的组装)就可以实现这样的功能!让功能的扩充变得简单!
在代码的实现上,功能实现是编写代码的第一步,而我们的大多程序员都做到了第一步,想要获得更高的薪水,就要有些和其他人不一样的东西,那么,这时候,业务来理解水平,抽象能力,实现能力,优化能力,逐渐在以后的晋升中起到至关重要的作用,而这些能力有一个公共的父类,就是全局观,在全局上考虑问题,包含时间与空间两个方向,当时间长了,变化怎么办?人数多了,数据量大了怎么办?
成为一个优秀的架构人员,我们要学习的还有很多!
时间: 2024-11-01 17:29:27