1. 程式人生 > 其它 >Spring深入淺出(十三),AOP,基於註解開發

Spring深入淺出(十三),AOP,基於註解開發

一、概述

在 Spring 中,儘管使用 XML 配置檔案可以實現 AOP 開發,但是如果所有的相關配置都集中在配置檔案中,勢必會導致 XML 配置檔案過於臃腫,從而給維護和升級帶來一定的困難。
為此,AspectJ 框架為 AOP 開發提供了一套註解。AspectJ 允許使用註解定義切面、切入點和增強處理,Spring 框架可以根據這些註解生成 AOP 代理。

名稱說明
@Aspect 用於定義一個切面。
@Pointcut 用於定義一個切入點。
@Before 用於定義前置通知,相當於 BeforeAdvice。
@AfterReturning 用於定義後置通知,相當於 AfterReturningAdvice。
@Around 用於定義環繞通知,相當於MethodInterceptor。
@AfterThrowing 用於定義丟擲通知,相當於ThrowAdvice。
@After 用於定義最終final通知,不管是否異常,該通知都會執行。
@DeclareParents 用於定義引介通知,相當於IntroductionInterceptor(不要求掌握)。

啟用 @AspectJ 註解有以下兩種方法:

1)使用@Configuration和@EnableAspectJAutoProxy註解

@Configuration 
@EnableAspectJAutoProxy
public class Appconfig { }

2)基於XML配置

<aop:aspectj-autoproxy>

3)相關類庫的引用,參考上一篇文章Spring深入淺出(十二),AOP,基於XML開發

二、基於 AOP 的 @AspectJ 示例

1. 建立aspect 模組

package com.clzhang.spring.demo;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.AfterReturning; @Aspect public class Logging { /** * Following is the definition for a pointcut to select all the methods * available. So advice will be called for all the methods. */ @Pointcut("execution(* com.clzhang.spring.demo.*.*(..))") private void selectAll() { } /** * This is the method which I would like to execute before a selected method * execution. */ @Before("selectAll()") public void beforeAdvice() { System.out.println("Going to setup student profile."); } /** * This is the method which I would like to execute after a selected method * execution. */ @After("selectAll()") public void afterAdvice() { System.out.println("Student profile has been setup."); } /** * This is the method which I would like to execute when any method returns. */ @AfterReturning(pointcut = "selectAll()", returning = "retVal") public void afterReturningAdvice(Object retVal) { System.out.println("Returning:" + retVal.toString()); } /** * This is the method which I would like to execute if there is an exception * raised by any method. */ @AfterThrowing(pointcut = "selectAll()", throwing = "ex") public void AfterThrowingAdvice(IllegalArgumentException ex) { System.out.println("There has been an exception: " + ex.toString()); } }

2. 建立Bean類

package com.clzhang.spring.demo;

public class Student {
    private Integer age;
    private String name;

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getAge() {
        System.out.println("Age : " + age);
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        System.out.println("Name : " + name);
        return name;
    }

    public void printThrowException() {
        System.out.println("Exception raised");
        throw new IllegalArgumentException();
    }
}

3. 建立主程式

package com.clzhang.spring.demo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");
      Student student = (Student) context.getBean("student");
      System.out.println("-----Invoke getName begin-----");
      String myName = student.getName();
      System.out.println("-----Invoke getName end. Name is:" + myName + "----");
      student.getAge();     
      student.printThrowException();
   }
}

4. 建立配置檔案

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

   <aop:aspectj-autoproxy/>

   <!-- Definition for student bean -->
   <bean id="student" class="com.clzhang.spring.demo.Student">
      <property name="name"  value="Zara" />
      <property name="age"  value="11"/>      
   </bean>

   <!-- Definition for logging aspect -->
   <bean id="logging" class="com.clzhang.spring.demo.Logging"/> 

</beans>

5. 執行輸出

-----Invoke getName begin-----
Going to setup student profile.
Name : Zara
Student profile has been setup.
Returning:Zara
-----Invoke getName end. Name is:Zara----
Going to setup student profile.
Age : 11
Student profile has been setup.
Returning:11
Going to setup student profile.
Exception raised
Student profile has been setup.
There has been an exception: java.lang.IllegalArgumentException

本文參考:

https://www.w3cschool.cn/wkspring/k4q21mm8.html