1. 程式人生 > >Spring Boot +Spring AOP 可插拔式日誌思路

Spring Boot +Spring AOP 可插拔式日誌思路

       Spring 基於IOC容器管理Bean的方式,使得其有能力對IOC容器中的所有Bean進行無限可能的操作,Spring AOP是基於 IOC容器的高階特性,藉助與AOP能實現一些可插拔模組,而不影響原有系統的設計.

        本節結合Spring Boot 在一個已有的Web專案中使用AOP提供一種後續的日誌補救方案.更多關於IOC容器的概念請查詢相關資源,附件中提供AOP學習的簡要筆記,僅供參考

  • Spring Boot 程式主類 ZkClientApplication, 考慮到該類的註解已經"足夠多",當然基於Java註解的配置方式是不可避免的,決定在維護一個配置類ZkClientConfiguration,相關程式碼如下:

ZkClientApplication.java ,該類中僅是Spring Boot +Spring Cloud 相關的配置,無須關注.

@SpringBootApplication
// 啟用REST 客戶端
@EnableFeignClients
// 啟用客戶端負載均衡
@RibbonClient(name = "my", configuration = RibbonConfig.class)
// 啟用服務發現
@EnableDiscoveryClient
// 啟用斷路器
@EnableHystrix
@ComponentScan("cn.com.xiaofen")
public class ZkClientApplication {
	public static void main(String[] args) {
		SpringApplication.run(ZkClientApplication.class, args);
	}
	/* Spring JDBC */
	@Bean
	public JdbcTemplate primaryJdbcTemplate(DataSource dataSource) {
		return new JdbcTemplate(dataSource);
	}

	/* TOMCAT DataSourcePool */
	@Bean
	@ConfigurationProperties(prefix = "spring.datasource")
	public DataSource dataSource() {
		return DataSourceBuilder.create().build();
	}
}

ZkClientConfiguration.java ,註解@EnableAspectJAutoProxy啟用Spring對AOP的支援並允許通過註解的方式定義AOP例項.
@Configuration
// 啟用AOP註解特性
@EnableAspectJAutoProxy
public class ZkClientConfiguration {

  • 本接目標是完成對cn.com.xiaofen.controller 包下的控制器的訪問進行監控,記錄訪問的行為,當然如果有一種可行的思路,那就有無限可能.專案包結果如下:
  • 在log包下定義RequestLog.java 用於定義AOP切面並切入所有controller包下的類列印訪問日誌,這裡並沒有複雜的操作,實際上在生產環境中日誌可以有更高階的處理方式如統一發送到訊息系統kafka,mq等統一處理.

RequestLog.java , 原始碼如下,稍後做簡單的答疑.

@Aspect
@Component
public class RequestLog {
	public static final Log log = LogFactory.getLog(RequestLog.class);

	// defined aop pointcut
	@Pointcut("execution(* cn.com.xiaofen.controller.*.*(..))")
	public void controllerLog() {
	}

	// log all of controller
	@Before("controllerLog()")
	public void before(JoinPoint joinPoint) {
		log.info(joinPoint.getSignature().getDeclaringType() + ",method:" + joinPoint.getSignature().getName()
				+ ",params:" + Arrays.asList(joinPoint.getArgs()));
	}

	// result of return
	@AfterReturning(pointcut = "controllerLog()", returning = "retVal")
	public void after(JoinPoint joinPoint, Object retVal) {
		System.out.println(retVal);
	}

}

  • @Aspect 申明當前類賦予一個介面的特殊使命,@Component 註解是為了讓當前類的例項為IOC容器感知, Spring IOC容器會自動檢查載入@Aspect 標識的例項以提取定義的AOP特性.
  • 在使用AOP之前需要定一個PointCut 切口,即那具體到哪些方法可以被切面切入. @Pointcut("execution(* cn.com.xiaofen.controller.*.*(..))")  註解標識的方法定義了一個PointCut 定義了cn.com.xiaofen.controller 包下所有類的任意數量引數的方法. 引用該切口的方式為當前方法名 +() 即可.
  • @Before("controllerLog()") 定義前置通知,是AOP的基本單元即切點,即在掉用目標方法之前處理一些操作, 註解標註的方法中可以使用JoinPoint  來訪問當前正要訪問的方法的簽名信息等.此處獲取了類名,方法名,以及提交的引數資訊等,正是進行日誌列印所需要的.
  • @AfterReturning 定義返回通知,方法釣用結束,可以獲取到目標方法執行的結果.其它可參考附件

附件:

一、String AOP程式設計

    .AOP(Aspect-Orientrd Programming,面向切面程式設計),是一種新的方法論,是對傳統OOP(Object Oriented Programming,面向物件程式設計)的補充。
    .AOP 的主要程式設計物件是切面(aspect) ,而切面模組化橫切關注點
    .在引用AOP程式設計時,任然需要定義公共功能,但可以明確定義這個功能在哪裡,以什麼方式應用,並且不修改受影響的類,這樣一來橫切關注點就被模組化到特俗的物件(切面)裡
    .AOP的好處
        .每個事物邏輯位於一個位置,程式碼不分散,便於升級和維護
        .業務模組更加簡潔,只包含核心業務程式碼

二、AOP術語
    .切面(Aspect),橫切關注點(跨越應用程式多個模組的功能)被模組化的特殊物件
    .通知(Advice),切面必須要完成的工作
    .代理(Proxy),向目標物件應用通知之後建立的物件

    [email protected]連結點(Joinpoint) 程式執行的某個特定位置



    [email protected]切點(Pointcut) 每個類擁有多個連線點





三、Spring AOP
    .AspectJ:Java社群裡最完整最流行的AOP框架

    .在Spring2.0以上版本中,可以使用AspectJ註解或基於XML配置AOP

    1.Spring中啟用AspectJ
        .加入Spring 的 jar  && AspectJ jar && aopalliance-1.0.jar
        
            spring-aop-4.2.3.RELEASE.jar
            spring-aspects-4.2.3.RELEASE.jar
            spring-beans-4.2.3.RELEASE.jar
            spring-context-4.2.3.RELEASE.jar
            spring-core-4.2.3.RELEASE.jar
            spring-expression-4.2.3.RELEASE.jar
            commons-logging-1.2.jar

            aspectjrt.jar
            aspectjtools.jar
            aspectjweaver.jar
            org.aspectj.matcher.jar
        .在Spring配置檔案中加入AOP的名稱空間

            .xmlns:aop="http://www.springframework.org/schema/aop"

        .基於註解的配置
            .<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
            .把橫切關注點的程式碼抽象到切面的類中
                .將切面加入IOC容器中
                    [email protected]
                .宣告為切面
                    [email protected]
            .宣告通知
                .申明一個方法
                [email protected]    -->前置通知,在方法執行之前執行
                    [email protected]("execution(public void cn.com.zjf.hello.Hello.*(String ))")

                [email protected]        -->後置通知,在方法執行之後執行
                [email protected]    -->返回通知,在方法返回結果之後執行
                [email protected]    -->異常通知,在方法丟擲異常之後
                [email protected]    -->環繞通知,圍繞著方法執行
            **使用方法簽名編寫AdpectJ 切入點表示式
                .execution * com.zjf.hello.*(..):
                    .第一個 * 代表任意修飾符及任意返回值.
                    .第二個 * 代表任意方法. .. 匹配任意數量的引數.
                    .若目標類與介面與該切面在同一個包中, 可以省略包名.

                .execution public String hello.*(double, ..)
                    .匹配第一個引數為 double 型別的方法,
                    ^.. 匹配任意數量任意型別的引數



            **可以在通知的方法中加入 JoinPoint joinPoint 來獲取通知的細節
                .public void beforeMethod(JoinPoint joinPoint){}




        [email protected]        後置通知

            .同前置通知
            .不能目標訪問方法的返回結果


        [email protected]
            .返回通知,方法正常執行時的通知
            .可以訪問目標方法的返回值

        [email protected]

            .異常通知,方法異常執行後的通知
            .可以訪問異常資訊,及具體的異常物件
        [email protected]
            
            .環繞通知
            .    @Around(value="execution(* cn.com.zjf.hello.Hello.*(String ))")
                public void afterAroundMethod(ProceedingJoinPoint pjp){



    2.指定切面的優先順序
        [email protected](1)    -->值越小優先順序越高




    3.重用切入點表示式
        .新增一個方法用來申明切入點表示式,該方法中不在需要加入其它的程式碼
        .使用@PointCut來申明切入點表示式
            [email protected](value="execution(* cn.com.zjf.hello.Hello.*(String ))")
                public void declareJoinPointExpression(){
        
            }
        .後面的其他切入點使用方法名來引用
            [email protected]("declareJoinPointExpression()")

            .不同包中可以使用包名.類名.方法名()來訪問





    4.基於配置檔案的方式來配置AOP

        .配置切面的Bean
            .<bean id="logginAspect" class="cn.com.zjf.hello.LogginAspect"></bean>
        .使用<aop:config> 配置AOP
            .配置切點表示式
                .<aop:pointcut expression="execution(* cn.com.zjf.hello.Hello.*(..))" id="logging"/>
            .配置切面及通知
                .<aop:aspect ref="validateAdpect" order="1">
                    <aop:before method="validate" pointcut-ref="logging"/>
                 </aop:aspect>

相關推薦

Spring Boot +Spring AOP 日誌思路

       Spring 基於IOC容器管理Bean的方式,使得其有能力對IOC容器中的所有Bean進行無限可能的操作,Spring AOP是基於 IOC容器的高階特性,藉助與AOP能實現一些可插拔模組,而不影響原有系統的設計.         本節結合Spring Bo

帶你手寫基於 Spring RPC 框架(一)介紹

目錄: 帶你手寫基於 Spring 的可插拔式 RPC 框架(一)介紹 帶你手寫基於 Spring 的可插拔式 RPC 框架(二)整體結構 帶你手寫基於 Spring 的可插拔式 RPC 框架(三)通訊協議模組 帶你手寫基於 Spring 的可插拔式 RPC 框架(四)代理類的注入與服務啟動 帶你手寫基於 S

Spring Boot使用AOP搭建統一處理請求日誌和使用log4j記錄不同級別的日誌

受http://blog.didispace.com/springbootaoplog/啟發,今天給Spring Boot專案搭建了統一處理請求日誌的切面並引入log4j記錄不同層級日誌。 mark一下這個過程,以及原文中沒有涉及到的一些疑問 一.  新增要使用的依賴&nbs

CMDB 資產采集——拓展思想

資產采集 pat eve nbsp sel one ddp pre ram 功能描述 每個資產采集的插件都是一個獨立的py腳本統一放在一個目錄下,所有插件的路徑統一配置在settings.py 配置文件中,以字典形式配置。通過for 循環字典中插件逐個執行插件采集數據。增

# ""元件設計,領略元件開發的奧祕

從一個 Confirm 元件開始,一步步寫一個可插拔式的元件。 處理一個正常的支付流程(比如支付寶購買基金) 點選購買按鈕 如果風險等級不匹配則:彈確認框(Confirm) 使用者確認風險後:彈出支付方式選擇彈窗(Dialog) 選擇好支付方式後:彈窗呼叫指紋驗證(Dialog) 如果關閉指紋驗證:提示是否

Spring Boot學習——AOP編程的簡單實現

col .com tsig 訪問 pan -s ping 編程範式 lan 首先應該明白一點,AOP是一種編程範式,是一種程序設計思想,與具體的計算機編程語言無關,所以不止是Java,像.Net等其他編程語言也有AOP的實現方式。AOP的思想理念就是將通用邏輯

Spring Bootaop中獲取request對象

stat class gpo thold t對象 對象 pat ring before doBefore(){ ServetRequestAttrbtes attributes = (ServetRequestAttrbtes)RequestContextHolder.

Spring Boot Maven 打包執行Jar文件!

project inux dep font feed spring 必須 connect plain Maven pom.xml 必須包含 [plain] view plain copy <packaging>jar</

Spring Boot 應用AOP

通知 匹配 ide CA AS 結束 RR 依賴 表示 # Spring Boot 應用AOP 一、在pom中添加依賴 <dependency> <groupId>org.springframework.boot</groupId>

Spring Boot使用AOP實現攔截某個方法

ces 文件 commit ransac dex red code join info 1、引入.jarl文件依賴 <!-- Spring Boot Web 依賴 --> <dependency>

spring boot配置分頁

turn span 依賴 inf factory jaxb 其中 nbsp ica 在springboot中使用PageHelper插件有兩種較為相似的方式,接下來我就將這兩種方式進行總結。 方式一:使用原生的PageHelper 1.在pom.xml中引入依賴

Spring Boot使用AOP實現REST接口簡易靈活的安全認證

all 高級 mes 之前 接口 封裝 msg mage ror 本文將通過AOP的方式實現一個相對更加簡易靈活的API安全認證服務。 我們先看實現,然後介紹和分析AOP基本原理和常用術語。 一、Authorized實現1、定義註解 package com.power.de

Spring Boot(四)開啟宣告事務

簡介 以前用Spring想要用事務的時候,都需要自己在spring的配置檔案中配置事務管理器。而Spring Boot則預設對jpa,jdbc,mybatis開啟了事務,引入他們的依賴的時候,事務就開啟了。使用事務只需要一個@Transactional註解就可以了。 準備 以上一篇文章【

spring mvc和spring boot實現AOP

spring boot實現AOP 首先建立切面類需要@Aspect,@Component註解 然後建立@Pointcut確定什麼方法實現aop @Pointcut("execution(* com.air_baocl.controller.selectApi.*(..))")

Spring Boot系列——AOP配自定義註解的最佳實踐

AOP(Aspect Oriented Programming),即面向切面程式設計,是Spring框架的大殺器之一。 首先,我宣告下,我不是來系統介紹什麼是AOP,更不是照本宣科講解什麼是連線點、切面、通知和切入點這些讓人頭皮發麻的概念。 今天就來說說AOP的一些應用場景以及如何通過和其他特性的結合提升

Spring-boot 配置Aop獲取controller裡的request中的引數以及其返回值

轉自:http://ysj5125094.iteye.com/blog/2151855 前提條件: 除了spring相關jar包外,還需要引入aspectj包。 Xml程式碼  <dependency>     

spring boot實現AOP登入攔截

1.在pom.xml中新增配置 <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifac

spring-boot maven打包執行jar

一. pom.xml中加入依賴 <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-p

Spring boot 結合aop,自定義註解,切面的理解

package com.imooc.boot.controller; import com.imooc.boot.aspect.IndexAspect; import org.springframework.web.bind.annotation.RequestMapping; import

Spring BootAOP統一處理HTTP請求

版權宣告:博主原創/資料整理,轉載請註明出處!! 首先,AOP (Aspect Oriented Programming )指面向切面程式設計,通過預編譯方式或者執行時刻對目標物件動態地新增功能。 一、Spring Boot中新增AOP依賴 <