欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
一些開(kāi)源框架中AOP的實(shí)現方法

一些開(kāi)源框架中AOP的實(shí)現方法

一些開(kāi)源框架中AOP的實(shí)現方法

首先說(shuō)說(shuō)Webwork中的Interceptor。

下面是XWorkInterceptor接口的src

package com.opensymphony.xwork.interceptor;

import com.opensymphony.xwork.ActionInvocation;

 

public interface Interceptor {

    void destroy();

    void init();

    String intercept(ActionInvocation invocation) throws Exception;

}

 

一般情況下如果要自己定義攔截器只需要實(shí)現Intercptor這個(gè)接口即可。在覆寫(xiě)intercept方法的時(shí)候注意要對invocation進(jìn)行invoke調用。這個(gè)方法的作用是執行攔截器鏈上的下一個(gè)環(huán)節,如果沒(méi)有攔截器那么就執行Action。何servlet里面的filter非常相似。在攔截器中可以通過(guò)ServletActionContext獲得相關(guān)的數據比如Session里面的數據或者Paramater里面的數據等等。XWorkActionContext這個(gè)類(lèi)里面是以Map的形式來(lái)存儲各類(lèi)數據,所以是和容器解耦的。在WW里面的ServletActionContext則是負責把web容器里面的request,session之類(lèi)的東西綁到Map上面,讓整個(gè)鏈上的每個(gè)環(huán)節都可以使用參數。

當然也可以繼承XWorkAroundInterceptor,利用模版模式(Template Design Pattern)來(lái)實(shí)現前攔截和后攔截。

public abstract class AroundInterceptor implements Interceptor {

     public String intercept(ActionInvocation invocation) throws Exception {

        String result = null;

        before(invocation);

        result = invocation.invoke();

        after(invocation, result);

        return result;

    }

    protected abstract void after(ActionInvocation dispatcher, String result) throws Exception;

    protected abstract void before(ActionInvocation invocation) throws Exception;

}

 

上面這種純粹利用類(lèi)的繼承來(lái)解決方法的攔截。

下面說(shuō)說(shuō)利用Proxy這個(gè)類(lèi)來(lái)實(shí)現動(dòng)態(tài)代理。

首先回顧一下設計模式中的Proxy Design Pattern。有一個(gè)業(yè)務(wù)接口,有一個(gè)業(yè)務(wù)實(shí)現類(lèi),然后業(yè)務(wù)實(shí)現類(lèi)實(shí)現這個(gè)接口,這時(shí)我自己人工添加一個(gè)代理類(lèi)也實(shí)現業(yè)務(wù)接口,同時(shí)聚合一個(gè)業(yè)務(wù)實(shí)現類(lèi)的對象,在實(shí)現業(yè)務(wù)接口方法的時(shí)候委派被代理類(lèi)(業(yè)務(wù)是實(shí)現類(lèi))執行,同時(shí)在執行前后干些額外的事情,現在就說(shuō)說(shuō)這個(gè)代理類(lèi)的生成方法。

首先Person接口中有love方法,然后PersonImpl實(shí)現類(lèi)。我需要在Person調用love方法的前后加入日志記錄的功能,同時(shí)必須保證透明性。即Person接口的使用者對logger一無(wú)所知。

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

 

public class LoggingProxy implements InvocationHandler {

 

//下面這個(gè)是生成一個(gè)動(dòng)態(tài)代理的類(lèi)的方法,注意接口可以隨自己制定,但是必須有被代理對象obj作為參數,返回值是代理//對象。

    public static Object newLogginPorxyAround(Logger logger, Object obj) {

       return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj

              .getClass().getInterfaces(), new LoggingProxy(logger, obj));

    }

 

    private Object proxiedObject;

 

    private Logger logger;

 

    private LoggingProxy(Logger l, Object obj) {

       logger = l;

       proxiedObject = obj;

    }

 

//這個(gè)是實(shí)現接口的時(shí)候必須覆寫(xiě)的方法,可以告訴代理類(lèi)被攔截方法的Method對象和方法的參數列表Object[] args

    public Object invoke(Object proxy, Method method, Object[] args)

           throws Throwable {

       Object result = null;

       try {

           logger.info("Entering method " + method.getName());

           result = method.invoke(proxiedObject, args);

       } catch (Exception x) {

           logger.warn("Unexpected exception " + x + " invoking "

                  + method.getName());

       } finally {

           logger.info("Exiting method " + method.getName());

       }

 

       return result;

    }

}

 

下面看一下Proxy.newProxyInstancesrc

public static Object newProxyInstance(ClassLoader loader,

Class<?>[] interfaces, InvocationHandler h)

{  

    //注意省略了一些try catch

Class cl = getProxyClass(loader, interfaces);

//constructorParams的定義

// private final static Class[] constructorParams =  { InvocationHandler.class };

Constructor cons = cl.getConstructor(constructorParams);

return (Object) cons.newInstance(new Object[] { h });

}

可以看到一個(gè)代理的Object就這樣被制造出來(lái)了。

下面看看客戶(hù)端使用情況

Logger personLogger = new Logger();

Person p = new PersonImpl();

p=(Person)LoggingProxy.newLogginPorxyAround(personLogger,p);

p.love();

獲得代理對象后需要轉型為接口類(lèi)型,當然可以利用泛型,減少類(lèi)型轉換,不過(guò)用了泛型static方法返回T是無(wú)法通過(guò)編譯的。在運行的結果中可以看到方法的前后都會(huì )有日志輸出。

首先必須明確一點(diǎn),使用動(dòng)態(tài)代理必須有一個(gè)業(yè)務(wù)接口的存在,否則一切無(wú)從談起,如果把這個(gè)例子修改成PersonImpl p = new PersonImpl();然后去生成動(dòng)態(tài)代理運行的時(shí)候是會(huì )出錯的。

那么假設我有一個(gè)類(lèi),沒(méi)有對應的接口,我想對他的方法進(jìn)行AOP如何實(shí)現呢?一般來(lái)說(shuō)都是采用修改字節碼的方法。在這方面CGLib是首選,當然還有威力更加強大的AspectJ,利用代碼的織入實(shí)現AOP。

下面是一個(gè)利用CGLib來(lái)運行時(shí)修改字節碼的例子

e.g.

import java.lang.reflect.Method;

 

import net.sf.cglib.proxy.Enhancer;

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

 

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

 

public class AOPInstrumenter implements MethodInterceptor {

 

    private static Log logger = LogFactory.getLog(AOPInstrumenter.class);

 

    private Enhancer enhancer = new Enhancer();

 

    public Object getInstrumentedClass(Class clz) {

       enhancer.setSuperclass(clz);

       enhancer.setCallback(this);

       return enhancer.create();

    }

 

    public Object intercept(Object o, Method method, Object[] methodParameters,

           MethodProxy methodProxy) throws Throwable {

       logger.debug("Before Method =>" + method.getName());

       Object result = methodProxy.invokeSuper(o, methodParameters);

       logger.debug("After Method =>" + method.getName());

       return result;

    }

 

    public static void main(String args[]) {

       AOPInstrumenter aopInst = new AOPInstrumenter();

 

       PersonImpl pi = (PersonImpl) aopInst

              .getInstrumentedClass(PersonImpl.class);

       pi.love();

    }

}

 

AspectJ 的用法就不多說(shuō)了。上面的動(dòng)態(tài)代理和CGLib修改字節碼就是SpringFrameworkAOP框架的實(shí)現原理,同時(shí)也是申明式事務(wù)管理的基礎。Rod曾經(jīng)拿Spirng AOPAspectJ做比較(詳見(jiàn)Without EJB),兩者的缺點(diǎn)和優(yōu)點(diǎn)他都說(shuō)了,但是他更加傾向于使用Spring AOP,畢竟是自己的東西。一般項目中如果沒(méi)有特殊需求應該不會(huì )用到AspectJ。一般來(lái)說(shuō)AOP用來(lái)做權限和事務(wù)管理效果比較好,這樣在業(yè)務(wù)代碼中就可以少掉很多重復冗余的代碼,而且可以在后期一次性加上。對于權限一般簡(jiǎn)單的應用可以采用wwinterceptor,復雜一點(diǎn)的推薦使用基于SpringAcegi框架,這個(gè)東西的配置實(shí)在是繁瑣,而且使用和理解也頗有難度。他的官方demo把權限配置在XML文件中對于企業(yè)級應用來(lái)說(shuō)是毫無(wú)意義的,等于是玩具,因為權限一旦膨脹維護這個(gè)XML文件簡(jiǎn)直是噩夢(mèng)一般。但是可以自己進(jìn)行數據庫擴展,遵循RBAC模型resource(function)/permission/role/user.它可以實(shí)現3種級別的攔截分別是 URL,function,acl(粒度是domain的方法,很細很細了).一般來(lái)說(shuō)到urlfunction就可以完成對所有資源的控制了.關(guān)于Acegi的設計說(shuō)明可以參考Professional.Java.Development.with.the.Spring.Framework一書(shū).

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Java - AOP編程入門(mén)--Java篇
spring ioc 原理 spring aop原理 - 本事記的富偉徐 - JavaEy...
反射實(shí)現 AOP 動(dòng)態(tài)代理模式(Spring AOP 的實(shí)現 原理) - Java 例子 ...
Spring aop的實(shí)現原理
Spring框架與AOP思想的研究與應用
AOP及其在Spring中的應用(一)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久