java架構解密——即時動態aop

來源:互聯網
上載者:User

標籤:

  在上篇部落格中個,咱們一起組建了一個容器,裡面封裝了業務,這樣,咱們就將業務和服務的組裝放到了用戶端,而用戶端就相當於咱們的開發中使用到的設定檔,大家發現問題了嗎?就是我不能動態改動了?業務容器在代理完成後,重新添加一個容器,這時候,是不被允許的,那這個容器就是個編譯時間起作用的容器,他就喪失了很多的靈活性!  那怎麼辦呢?實際就是調換一下調用順序就好,大家看看結果:
1,類圖對比

  改造後類圖

2,代碼實現:2.1代理類的變化:
/** * 打招呼動態代理類,給業務類添加功能 * 前一版本為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;    }}
2.2業務容器
/** * 業務類容器: *  用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;    }}
2.3 用戶端
/** * 執行代理程式的用戶端 * * @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();    } }
3,總結
    代碼的靈活,就像生活一般,在代碼靈活的過程中,我們就會對比下生活,生活中,我們每個人,事,物都是獨立的對象,而在生活中的時間軸中,我們也是過程化的組織,我們的代碼和生活,在思想上都是相同的,最佳化的不僅僅是代碼,還有思想啊!

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

java架構解密——即時動態aop

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.