成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

使用Cglib動態(tài)代理實(shí)現(xiàn)事務(wù)管理器

Big_fat_cat / 3019人閱讀

摘要:使用動態(tài)代理的好處是,反射機(jī)制可以生成任意類型的動態(tài)代理類。暫時(shí)不做處理得到類名得到方法名創(chuàng)建實(shí)例動態(tài)代理實(shí)現(xiàn)事務(wù)得到方法調(diào)用的方法在中實(shí)現(xiàn)了的接口?;謴?fù)事務(wù)的默認(rèn)提交方式關(guān)閉數(shù)據(jù)庫連接

使用動態(tài)代理的好處是,Java反射機(jī)制可以生成任意類型的動態(tài)代理類。
如果使用proxy的動態(tài)代理的話,每個類都需要一個接口。Cglib是針對類來實(shí)現(xiàn)代理的,他的原理是對指定的目標(biāo)類生成一個子類,并覆蓋其中方法實(shí)現(xiàn)增強(qiáng)。

以下是我使用Cglib來實(shí)現(xiàn)事務(wù)管理器的實(shí)例。
1、RouteDispatcherServlet.java
這個servlet主要是用于處理路由跳轉(zhuǎn)的問題,所有的Action跳轉(zhuǎn)都需要經(jīng)過這個servlet。路徑解析得到的類名和方法名,在此調(diào)用所有的Action方法。
同時(shí)事務(wù)也在這里實(shí)現(xiàn)。事務(wù)的實(shí)現(xiàn)由Cglib實(shí)現(xiàn)。

web.xml:


    RouteDispatcherServlet
    kit.RouteDispatcherServlet


    RouteDispatcherServlet
    /action/*
public class RouteDispatcherServlet extends HttpServlet {

    private static final long    serialVersionUID    = 3483132493821191287L;

    @Override
    public void init() throws ServletException {
        //暫時(shí)不做處理
    }
    
    @Override
    public void doGet(HttpServletRequest request,HttpServletResponse response){
        StringBuffer url = request.getRequestURL();
        
        //得到類名
        String actionNameTemp = url.substring(0,url.lastIndexOf("/"));
        String actionName = actionNameTemp.substring(actionNameTemp.lastIndexOf("/")+1);
        String actionWholeName = "action." + actionName;
        //得到方法名
        String methodName = url.substring(url.lastIndexOf("/")+1);
        
        try {
             //創(chuàng)建action實(shí)例
            BaseAction action =  (BaseAction)Class.forName(actionWholeName).newInstance();
            //動態(tài)代理實(shí)現(xiàn)事務(wù)
            TransactionCglib transactionCglib = new TransactionCglib();
            BaseAction baseActionCglib = (BaseAction) transactionCglib.getInstance(action);
            //得到方法
            Method m1 = baseActionCglib.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class );
            //調(diào)用baseActionCglib的m1方法
            m1.invoke(baseActionCglib, request, response);        
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
    
    @Override
    public void doPost(HttpServletRequest request,HttpServletResponse response){
        this.doGet(request, response);
    }
    
}

2、TransactionCglib.java
在TransactionCglib中實(shí)現(xiàn)了MethodInterceptor的接口。在這里需要導(dǎo)入兩個jar包:

public class TransactionCglib implements MethodInterceptor{

    private Object target;
    
    public TransactionCglib(){
        TransactionDao.getTransaction();//得到連接,開始事務(wù)
    }
    
    /**
     * 創(chuàng)建代理對象
     * 
     * @param target
     * @return
     */
    public Object getInstance(Object target){
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    
    
    /* (non-Javadoc)
     * 
     * 使用cglib實(shí)現(xiàn)事務(wù)
     * 
     */
    public Object intercept(final Object obj, Method method, final Object[] args, final MethodProxy proxy) throws Throwable {
        //事務(wù)開始
        TransactionManager transactionManager = new TransactionManager(TransactionDao.getConn());
        transactionManager.doTransaction(new Transaction(){    

            public void transaction() throws Exception {
                try {
                    proxy.invokeSuper(obj, args);
                } catch (Throwable e) {
                    throw new Exception(e);
                }
            }
        });
        
        return null;
    }

}

3、Transaction.java

public interface Transaction {
    
    public void transaction() throws Exception;

}

4、TransactionManager.java
TransactionManager體現(xiàn)了事務(wù)提交和rollback的流程,當(dāng)無異常時(shí)commit,當(dāng)有異常的時(shí)候,事務(wù)回滾rollback。

public class TransactionManager {
    
    private Connection conn;
    
    public TransactionManager(Connection conn){
        this.conn = conn;
    }
    
    public void doTransaction(Transaction transaction)  throws Exception{
    
        try {
            transaction.transaction();
            TransactionDao.commit();
        } catch (Exception e) {
            TransactionDao.rollback();
        }finally{
            //close
        }
        
    }
}

5、TransactionDao.java
TransactionDao中放置的是關(guān)于事務(wù)的詳細(xì)操作,包括getTransaction、commmit、rollback。需要注意的是,在這里,變量和方法都是靜態(tài)的,這就保證了在使用的時(shí)候僅僅只有一個connection,保證了事務(wù)的正確性。

public class TransactionDao {
    
    private static Connection conn;
    
    public static Connection getTransaction(){
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/tradition","root","sll");
            conn.setAutoCommit(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

    public static void commit(){
        try {
            conn.commit();
            conn.setAutoCommit(true);//恢復(fù)jdbc事務(wù)的默認(rèn)提交方式
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    
    public static void rollback(){
        try {
            conn.rollback();
            conn.close();//關(guān)閉數(shù)據(jù)庫連接
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static Connection getConn() {
        return conn;
    }

    public static void setConn(Connection conn) {
        TransactionDao.conn = conn;
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/65963.html

相關(guān)文章

  • 【Spring】一次線上@Transational事務(wù)注解未生效的原因探究

    摘要:由于的限制,無法替換被代理類已經(jīng)被載入的字節(jié)碼,只能生成并載入一個新的子類作為代理類,被代理類的字節(jié)碼依然存在于中。區(qū)別于前兩者,是一種靜態(tài)代理的實(shí)現(xiàn),即在編譯時(shí)或者載入類時(shí)直接修改被代理類文件的字節(jié)碼,而非運(yùn)行時(shí)實(shí)時(shí)生成代理。 現(xiàn)象描述 上周同事發(fā)現(xiàn)其基于mySql實(shí)現(xiàn)的分布式鎖的線上代碼存在問題,代碼簡化如下: @Controller class XService { @A...

    姘存按 評論0 收藏0
  • Java三種代理模式:靜態(tài)代理、動態(tài)代理cglib代理

    摘要:動態(tài)代理又被稱為代理或接口代理。靜態(tài)代理在編譯時(shí)產(chǎn)生字節(jié)碼文件,可以直接使用,效率高。代理無需實(shí)現(xiàn)接口,通過生成類字節(jié)碼實(shí)現(xiàn)代理,比反射稍快,不存在性能問題,但會繼承目標(biāo)對象,需要重寫方法,所以目標(biāo)對象不能為類。 一、代理模式介紹 代理模式是一種設(shè)計(jì)模式,提供了對目標(biāo)對象額外的訪問方式,即通過代理對象訪問目標(biāo)對象,這樣可以在不修改原目標(biāo)對象的前提下,提供額外的功能操作,擴(kuò)展目標(biāo)對象的功...

    Kaede 評論0 收藏0
  • 吃透動態(tài)代理,解密spring AOP源碼(四)

    摘要:值得一提的是由于采用動態(tài)創(chuàng)建子類的方式生成代理對象,所以不能對目標(biāo)類中的方法進(jìn)行代理。動態(tài)代理中生成的代理類是子類,調(diào)試的時(shí)候可以看到,打開源碼可看到實(shí)現(xiàn)了和也就實(shí)現(xiàn)方法。 前面講到了動態(tài)代理的底層原理,接下來我們來看一下aop的動態(tài)代理.Spring AOP使用了兩種代理機(jī)制:一種是基于JDK的動態(tài)代理,一種是基于CGLib的動態(tài)代理. ①JDK動態(tài)代理:使用JDK創(chuàng)建代理有一個限制...

    Codeing_ls 評論0 收藏0
  • Java的三種代理模式

    Java的三種代理模式 參考:http://www.cnblogs.com/cenyu/...Java核心技術(shù)原書第九版6.5節(jié) 為什么使用代理   我們在寫一個功能函數(shù)時(shí),經(jīng)常需要在其中寫入與功能不是直接相關(guān)但很有必要的代 碼,如日志記錄,信息發(fā)送,安全和事務(wù)支持等,這些枝節(jié)性代碼雖然是必要的,但它會帶來以下麻煩: 枝節(jié)性代碼游離在功能性代碼之外,它不是函數(shù)的目的,這是對OO是一種破壞 枝節(jié)性...

    Rango 評論0 收藏0
  • 設(shè)計(jì)模式之代理模式

    摘要:下面我們通過玩英雄聯(lián)盟代練的例子來說明下登錄游戲贏下了一局英雄聯(lián)盟,獲得了金幣測試結(jié)果登錄游戲贏下了一局英雄聯(lián)盟,獲得了金幣可以這樣理解,自己寫代理類的方式就是靜態(tài)代理。 前言 剛上大學(xué)那會,英雄聯(lián)盟火的一塌糊涂,當(dāng)時(shí)每天都想著升到30級開啟排位之旅??墒巧?0級需要大把的時(shí)間不說,這時(shí)候匹配到的人,水平過于參差不齊,問候你全家的事經(jīng)常發(fā)生,那個時(shí)候就想要是能有個代練幫我升到30級該...

    xuweijian 評論0 收藏0

發(fā)表評論

0條評論

Big_fat_cat

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<