天天看點

使用aspectj模拟傳回消息

背景

有一個服務負責調用第三方服務,每個第三方的服務都設定了開關,開關打開的時候調用第三方服務擷取資料,開關關閉的時候傳回模拟資料。

這裡使用aspectj的around來攔截所有請求,如果是測試環境且滿足特定條件,加載模拟資料并傳回,否則調用真實服務。

aspectj官方文檔

http://www.eclipse.org/aspectj/doc/released/progguide/index.html

maven中的配置

增加aspectj依賴

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.8.9</version>
</dependency>
           

增加aspectj plugin配置

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.9</version>
</plugin>
           

eclipse安裝ajdt插件

插件位址: http://download.eclipse.org/tools/ajdt/46/dev/update

java項目轉為aspectj項目

選中項目,右鍵Configure-> Convert to AspectJ Project

eclipse會自動修改對應的配置檔案:

.classpath中增加

.project中javabuilder被修改為ajbuilder

<buildCommand>
    <name>org.eclipse.ajdt.core.ajbuilder</name>
    <arguments>
    </arguments>
</buildCommand>
           

攔截服務

public aspect MockServiceAspect {

    private static final Logger LOG = Logger.getLogger(MockServiceAspect.class);


    pointcut toolsRouter(Request request, BasicDBObject response) :  
        args(request, response) && execution(public void xx.xxx.xxx.ToolsRouter.route(Request, BasicDBObject));

    void around(Request request, BasicDBObject response) : toolsRouter(request, response) {
        try {
            String environment = Config.environment;
            String mockServices = Config.mockServices;
            String mockFilePath = Config.mockFilePath;          
            if(environment.contains("test") && StringUtils.isNotEmpty(mockServices)) {
                String uri = request.getUri();
                String filePath = "";
                String[] serviceArray = mockServices.split(",");                
                for(String service : serviceArray) {
                    if(uri.contains(service) && MgoUtil.hasShutdown(service)) {                 
                        filePath = mockFilePath + service + ".json";
                        break;
                    }
                }
                if(StringUtils.isNotEmpty(filePath)) {
                    LOG.info("uri:" + uri + ", 傳回模拟資料。");
                    String info = FileUtil.readAll(filePath);                   
                    BasicDBObject mockObj = StringUtil.parseJson(info);
                    response.clear();
                    response.putAll((BSONObject)mockObj);
                    LOG.info("uri:" + uri + ", mock response:" + response);
                    return;
                }
            }
            proceed(request, response);
        } catch (Exception e) {
            LOG.error("攔截服務出現異常, error:" + e.getMessage(), e);
        }       
    }

}

           

配置對應的服務及相應資料

config.properties中配置資料

mockServices=xxx,xxx,xx_xx,xxx
mockFilePath=xxx/  
           

把響應資料放到對應目錄下