標籤:大資料 架構 最佳化 解密 aop
在上篇部落格中,大家和我一起研究了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(類似於用戶端的組裝)就可以實現這樣的功能!讓功能的擴充變得簡單!
在代碼的實現上,功能實現是編寫代碼的第一步,而我們的大多程式員都做到了第一步,想要獲得更高的薪水,就要有些和其他人不一樣的東西,那麼,這時候,業務來理解水平,抽象能力,實現能力,最佳化能力,逐漸在以後的晉陞中起到至關重要的作用,而這些能力有一個公用的父類,就是全域觀,在全域上考慮問題,包含時間與空間兩個方向,當時間長了,變化怎麼辦?人數多了,資料量大了怎麼辦?
成為一個優秀的架構人員,我們要學習的還有很多!
java架構解密——深入再造AOP