Skip to content

Spring AOP 使用切面

1. Maven 配置文件 ( pom.xml ) 中添加依赖

xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>liujiajia-me</groupId>
        <artifactId>liujiajia-me-spring-learn</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>liujiajia-me-spring-learn-aop</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <version>1.5.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

2. 创建一个演奏接口(定义一个切点 perform

java
package concert;

/**
* Created by liujiajia on 2017/3/28.
*/
public interface Performance {
    public void perform();
}

3. 创建实现类

java
package concert;

import org.springframework.stereotype.Component;

/**
* Created by liujiajia on 2017/3/28.
*/
@Component
public class MusicConcert implements Performance {
    public void perform() {
        System.out.println("Playing music");
    }
}

4. 定义切面

使用 @Aspect 注解标记为切面。

使用 @After @AfterReturning @AfterThrowing @Around @Before 注解来声明通知方法,参数为切点表达式。可以使用 @Pointcut 注解来声明频繁使用的切点表达式。

java
package concert;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
* Created by liujiajia on 2017/3/28.
*/
@Aspect
@Component
public class Audience {
    // 表演之前
    @Before("execution(** concert.Performance.perform(..))")
    public void silenceCellPhones() {
        System.out.println("Silencing cell phones");
    }

    // 表演之前
    @Before("execution(** concert.Performance.perform(..))")
    public void takeSeats() {
        System.out.println("Taking seats");
    }

    // 表演之后
    @AfterReturning("execution(** concert.Performance.perform(..))")
    public void applause() {
        System.out.println("CLAP CLAP CLAP!!!");
    }

    // 表演失败之后
    @AfterThrowing("execution(** concert.Performance.perform(..))")
    public void demandRefund() {
        System.out.println("Demanding a refund");
    }
}

5. 在 JavaConfig 中使用 @EnableAspectJAutoProxy 注解启用 AspectJ 注解的自动代理

java
package concert;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
* Created by liujiajia on 2017/3/28.
*/
@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class ConcertConfig {

}

6. 创建测试类

java
package concert;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.assertEquals;

/**
* Created by liujiajia on 2017/3/28.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ConcertConfig.class)
public class AudienceTest {
    @Autowired
    private Performance performance;

    @Test
    public void performance() {
        performance.perform();
    }
}

7. 测试结果

Silencing cell phones
Taking seats
Playing music
CLAP CLAP CLAP!!!

8. 使用 @Pointcut 标注声明频繁使用的切点表达式

java
package concert;

import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
* Created by liujiajia on 2017/3/28.
*/
@Aspect
@Component
public class Audience {
    @Pointcut("execution(** concert.Performance.perform(..))")
    public void performance() {}

    // 表演之前
    @Before("performance()")
    public void silenceCellPhones() {
        System.out.println("Silencing cell phones");
    }

    // 表演之前
    @Before("performance()")
    public void takeSeats() {
        System.out.println("Taking seats");
    }

    // 表演之后
    @AfterReturning("performance()")
    public void applause() {
        System.out.println("CLAP CLAP CLAP!!!");
    }

    // 表演失败之后
    @AfterThrowing("performance()")
    public void demandRefund() {
        System.out.println("Demanding a refund");
    }
}

9. 使用 @Around 环绕通知

java
package concert;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
* Created by liujiajia on 2017/3/28.
*/
@Aspect
@Component
public class Audience {
    @Pointcut("execution(** concert.Performance.perform(..))")
    public void performance() {}

    @Around("performance()")
    public void watchPerformance(ProceedingJoinPoint jp) {
        try {
            System.out.println("Silencing cell phones");
            System.out.println("Taking seats");
            jp.proceed();
            System.out.println("CLAP CLAP CLAP!!!");
        } catch (Throwable e) {
            System.out.println("Demanding a refund");
        }
    }
}

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.