1. 程式人生 > >java使用動態代理來實現AOP(日誌記錄)的例項程式碼

java使用動態代理來實現AOP(日誌記錄)的例項程式碼

下面是一個AOP實現的簡單例子:

首先定義一些業務方法:

複製程式碼程式碼如下:
/**
 * Created with IntelliJ IDEA.
 * Author: wangjie  email:[email protected]
 * Date: 13-9-23
 * Time: 下午3:49
 */
public interface BussinessService {
    public String login(String username, String password);
    public String find();
}

public class BussinessServiceImpl implements BussinessService {
    private Logger logger = Logger.getLogger(this.getClass().getSimpleName());

    @Override
    public String login(String username, String password) {
        return "login success";
    }

    @Override
    public String find() {
        return "find success";
    }

}


複製程式碼程式碼如下:
/**
 * Created with IntelliJ IDEA.
 * Author: wangjie  email:[email protected]
 * Date: 13-9-24
 * Time: 上午10:27
 */
public interface WorkService {
    public String work();
    public String sleep();
}

public class WorkServiceImpl implements WorkService{
    @Override
    public String work() {
        return "work success";
    }

    @Override
    public String sleep() {
        return "sleep success";
    }
}


實現InvocationHandler介面,使用map來儲存不同的InvocationHandler物件,避免生成過多。 複製程式碼程式碼如下:
package com.wangjie.aoptest2.invohandler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.logging.Logger;

/**
 * Created with IntelliJ IDEA.
 * Author: wangjie  email:[email protected]
 * Date: 13-9-23
 * Time: 下午3:47
 */
public class LogInvoHandler implements InvocationHandler{
    private Logger logger = Logger.getLogger(this.getClass().getSimpleName());

    private Object target; // 代理目標
    private Object proxy; // 代理物件

    private static HashMap<Class<?>, LogInvoHandler> invoHandlers = new HashMap<Class<?>, LogInvoHandler>();

    private LogInvoHandler() {
    }

    /**
     * 通過Class來生成動態代理物件Proxy
     * @param clazz
     * @return
     */
    public synchronized static<T> T getProxyInstance(Class<T> clazz){
        LogInvoHandler invoHandler = invoHandlers.get(clazz);

        if(null == invoHandler){
            invoHandler = new LogInvoHandler();
            try {
                T tar = clazz.newInstance();
                invoHandler.setTarget(tar);
                invoHandler.setProxy(Proxy.newProxyInstance(tar.getClass().getClassLoader(),
                        tar.getClass().getInterfaces(), invoHandler));
            } catch (Exception e) {
                e.printStackTrace();
            }
            invoHandlers.put(clazz, invoHandler);

        }

        return (T)invoHandler.getProxy();
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Object result = method.invoke(target, args); // 執行業務處理

        // 列印日誌
        logger.info("____invoke method: " + method.getName()
                    + "; args: " + (null == args ? "null" : Arrays.asList(args).toString())
                    + "; return: " + result);


        return result;
    }

    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }

    public Object getProxy() {
        return proxy;
    }

    public void setProxy(Object proxy) {
        this.proxy = proxy;
    }
}


然後編寫一個Test類測試: 複製程式碼程式碼如下:
/**
 * Created with IntelliJ IDEA.
 * Author: wangjie  email:[email protected]
 * Date: 13-9-24
 * Time: 上午9:54
 */
public class Test {
    public static Logger logger = Logger.getLogger(Test.class.getSimpleName());
    public static void main(String[] args) {

        BussinessService bs = LogInvoHandler.getProxyInstance(BussinessServiceImpl.class);
        bs.login("zhangsan", "123456");
        bs.find();

        logger.info("--------------------------------------");

        WorkService ws = LogInvoHandler.getProxyInstance(WorkServiceImpl.class);
        ws.work();
        ws.sleep();

        logger.info("--------------------------------------");

        BussinessService bss = LogInvoHandler.getProxyInstance(BussinessServiceImpl.class);
        bss.login("lisi", "654321");
        bss.find();

    }
}


以後需要新增新的業務邏輯XXXService,只需要呼叫

XXXService xs = LogInvoHandler.getProxyInstance(XXXServiceImpl.class);

即可。

也可以模仿Spring等框架的配置,把bean的類名配置在xml檔案中,如:

<bean id="bussinessService" class="com.wangjie.aoptest2.service.impl.BussinessServiceImpl">

然後在java程式碼中解析xml,通過Class.forName("com.wangjie.aoptest2.service.impl.BussinessServiceImpl");獲得Class物件

然後通過LogInvoHandler.getProxyInstance(Class.forName("com.wangjie.aoptest2.service.impl.BussinessServiceImpl"));獲得代理物件Proxy

再使用反射去呼叫代理物件的方法。

執行結果如下:

九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: login; args: [zhangsan, 123456]; return: login success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: find; args: null; return: find success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.Test main
INFO: --------------------------------------
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: work; args: null; return: work success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: sleep; args: null; return: sleep success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.Test main
INFO: --------------------------------------
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: login; args: [lisi, 654321]; return: login success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: find; args: null; return: find success

相關推薦

java使用動態代理實現AOP(日誌記錄)的例項程式碼

下面是一個AOP實現的簡單例子: 首先定義一些業務方法: 複製程式碼程式碼如下: /**  * Created with IntelliJ IDEA.  * Author: wangjie  email:[email protected]  * Date: 13-9-23  * T

python實現AOP日誌記錄

前言 在Java中,AOP程式設計是一件比較通用方法,能夠少寫很多重複性的程式碼,讓程式自動幫我們完成,例如收集錯誤記錄,保證業務的事務性,無措提交,有錯回滾等。 最近寫了較多python程式碼,在python中,使用print 記錄日誌,但是每一個方法都要寫,比較麻煩,並且又不

java動態代理詳解,並用動態代理和註解實現日誌記錄功能

動態代理的概念       動態代理是程式在執行過程中自動建立一個代理物件來代替被代理的物件去執行相應的操作,例如, 我們有一個已經投入執行的專案中有一個使用者DAO類UserDao用來對User物件進行資料庫的增刪改查操作,但是有一天,要求在對使用者的增刪改查操作時記錄相

Java 動態代理AOP實現機制

www javadoc 底層 service ack 兩種方法 實現機制 之間 sets AOP實現機制http://www.iteye.com/topic/1116696 AOP: (Aspect Oriented Programming) 面向切面編程AOP包括切面(a

java代理,靜態代理動態代理以及spring aop代理方式,實現原理統一彙總 Spring中AOP的兩種代理方式(Java動態代理和CGLIB代理

若代理類在程式執行前就已經存在,那麼這種代理方式被成為 靜態代理 ,這種情況下的代理類通常都是我們在Java程式碼中定義的。 通常情況下, 靜態代理中的代理類和委託類會實現同一介面或是派生自相同的父類。 一、概述1. 什麼是代理我們大家都知道微商代理,簡單地說就是代替廠家賣商品,廠家“委託”代理為

Spring裡的aop實現方式和原始碼分析 java代理,靜態代理動態代理以及spring aop代理方式,實現原理統一彙總

使用"橫切"技術,AOP把軟體系統分為兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處基本相似,比如許可權認證、日誌、事務。AOP的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。

Mybatis(四):MyBatis核心元件介紹原理解析和原始碼解讀 java代理,靜態代理動態代理以及spring aop代理方式,實現原理統一彙總

Mybatis核心成員 Configuration        MyBatis所有的配置資訊都儲存在Configuration物件之中,配置檔案中的大部分配置都會儲存到該類中 SqlSession         &

(京東面試題)java動態代理主要怎麼實現的,spring aop 原理 如下類

京東面試題 1、java動態代理主要怎麼實現的,spring aop 原理 如下類 public class Test { public void example(){ System.out.println("example"); } } 如何實現在方法exampl

Java 動態代理(AOP實現機制)

浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>   

java動態代理實現

pan ack ger data- 動態代理 bind 使用 intercept framework 動態代理的實現 使用的模式:代理模式。代理模式的作用是:為其他對象提供一種代理以控制對這個對象的訪問。類似租房的中介。 兩種動態代理:(1)jdk動態代理,jdk動態代理是

淺談java中內置的觀察者模式與動態代理實現

所有 代理 notify play ani effect 一個 indicate protected 一.關於觀察者模式 1.將觀察者與被觀察者分離開來,當被觀察者發生變化時,將通知所有觀察者,觀察者會根據這些變化做出對應的處理。 2.jdk裏已經提供對應的Observer

Java動態代理學習【Spring AOP基礎之一】

tor -1 我們 null exception 文件 cat static 一個   Spring AOP使用的其中一個底層技術就是Java的動態代理技術。Java的動態代理技術主要圍繞兩個類進行的    java.lang.reflect.InvocationHan

[原創]Aop之使用Autofac+Castle 自動註入服務且動態代理服務實現攔截

bsp 實現 resolv typeof ica ner count cast ofa public static class AutofacComponentManualRegister { /// <summary>

Spring總結七:AOP動態代理實現

product div image style 攔截 throwable eth oid void Spring中的AOP代理可以使JDK動態代理,也可以是CGLIB代理,前者基於接口,後者基於子類。 首先我們來用代碼簡單演示jdk動態代理: 現在有一個商品的增刪改查的

2018-07-24期 Java動態代理實現數據庫連接池

iter 異常 ... lse system com link 是我 driver package cn.sjq.proxy.ds.pool;import java.io.PrintWriter;import java.lang.reflect.InvocationHand

AOP從靜態代理動態代理 Emit實現

spec oba e30 cda 調用 路由 orien emit .html 【前言】 AOP為Aspect Oriented Programming的縮寫,意思是面向切面編程的技術。 何為切面? 一個和業務沒有任何耦合相關的代碼段,諸如:調用日誌,發送郵件,甚至路由分發

JAVA 動態代理原理和實現

ror binary lose ole jdk 動態代理 參數 try lob rac 在 Java 中動態代理和代理都很常見,幾乎是所有主流框架都用到過的知識。在面試中也是經常被提到的話題,於是便總結了本文。 Java動態代理的基本原理為:被代理對象需要實現某個接口(這是

java動態代理之CGLIB實現

ssl return 其他 ase ger pac 父類 linked nic 動態代理(CGlib 與連接池的案例) Cglib代理: 針對類來實現代理,對指定目標 產生一個子類 通過方法攔截技術攔截所有父類方法的調用。 我們要使用cglib代理必須引入 cglib的j

java動態代理實現與原理詳細分析(【轉載】By--- Gonjan )

【轉載】By---    Gonjan    關於Java中的動態代理,我們首先需要了解的是一種常用的設計模式--代理模式,而對於代理,根據建立代理類的時間點,又可以分為靜態代理和動態代理。  一、代理模式  

java動態代理實現與原理詳細分析(【轉載】By--- Gonjan )

sleep class 實施 div prot stack 註意 san 由於 【轉載】By--- Gonjan 關於Java中的動態代理,我們首先需要了解的是一種常用的設計模式--代理模式,而對於代理,根據創建代理類的時間點,又可以分為靜態代理和動態代理。