Spring AOP AspectJ @After注解示例

Spring AOP AspectJ @After注解示例

原文: https://howtodoinjava.com/spring-aop/aspectj-after-annotation-example/

在这个 Spring aop 示例中,我们将学习使用 Aspectj @After注解。 @After带注解的方法在与切入点表达式匹配的所有方法之后准确运行。

在此示例中,我们将创建简单的 spring 应用程序,添加日志记录切面,然后基于在@After注解中传递的切入点信息来调用切面方法。

AspectJ @After注解用法

您可以按以下方式使用@After注解。

@Aspect
public class LoggingAspect {

    @After("execution(* com.howtodoinjava.app.service.impl.EmployeeManagerImpl.*(..))")
    public void logAfterAllMethods(JoinPoint joinPoint) { ... }

    @After("execution(* com.howtodoinjava.app.service.impl.EmployeeManagerImpl.getEmployeeById(..))")
    public void logAfterGetEmployee(JoinPoint joinPoint) { ... }
}

项目结构

Spring AOP Project Structure

Spring AOP 项目结构

Spring AOP AspectJ Maven 依赖关系

我添加了 spring 核心,spring aop 和 Aspectj 依赖项。

<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;
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.howtodoinjava</groupId>
    <artifactId>SpringAOPExamples</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Spring AOP Examples</name>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.9</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>
    </dependencies>
</project>

启用 AspectJ 支持

在 XML 配置文件中,您可以添加aop:aspectj-autoproxy元素以启用@AspectJ注解支持。

<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 ">

    <!-- Enable @AspectJ annotation support  -->
    <aop:aspectj-autoproxy />

    <!-- Employee manager -->
    <bean id="employeeManager" class="com.howtodoinjava.app.service.impl.EmployeeManagerImpl" />

    <!-- Logging Aspect -->
    <bean id="loggingAspect" class="com.howtodoinjava.app.aspect.LoggingAspect" />

</beans>

需要执行切面的服务方法

EmployeeManager.javaEmployeeManagerImpl.java

public interface EmployeeManager 
{
    public EmployeeDTO getEmployeeById(Integer employeeId);

    public List<EmployeeDTO> getAllEmployee();

    public void createEmployee(EmployeeDTO employee);

    public void deleteEmployee(Integer employeeId);

    public void updateEmployee(EmployeeDTO employee);
}

public class EmployeeManagerImpl implements EmployeeManager 
{
    public EmployeeDTO getEmployeeById(Integer employeeId) 
    {
        System.out.println("Method getEmployeeById() called");
        return new EmployeeDTO();
    }

    public List<EmployeeDTO> getAllEmployee() 
    {
        System.out.println("Method getAllEmployee() called");
        return new ArrayList<EmployeeDTO>();
    }

    public void createEmployee(EmployeeDTO employee)
    {
        System.out.println("Method createEmployee() called");
    }

    public void deleteEmployee(Integer employeeId) 
    {
        System.out.println("Method deleteEmployee() called");
    }

    public void updateEmployee(EmployeeDTO employee) 
    {
        System.out.println("Method updateEmployee() called");
    }
}

编写 AspectJ 注解的类和方法

用切入点信息编写 aspectj 注解的类和方法。

@Aspect
public class LoggingAspect {

    @After("execution(* com.howtodoinjava.app.service.impl.EmployeeManagerImpl.*(..))")
    public void logAfterAllMethods(JoinPoint joinPoint) 
    {
        System.out.println("****LoggingAspect.logAfterAllMethods() : " + joinPoint.getSignature().getName());
    }

    @After("execution(* com.howtodoinjava.app.service.impl.EmployeeManagerImpl.getEmployeeById(..))")
    public void logAfterGetEmployee(JoinPoint joinPoint) 
    {
        System.out.println("****LoggingAspect.logAfterGetEmployee() : " + joinPoint.getSignature().getName());
    }

    @After("execution(* com.howtodoinjava.app.service.impl.EmployeeManagerImpl.createEmployee(..))")
    public void logAfterCreateEmployee(JoinPoint joinPoint) 
    {
        System.out.println("****LoggingAspect.logAfterCreateEmployee() : " + joinPoint.getSignature().getName());
    }
}

测试 Spring AspectJ 的配置和执行

现在,我们来测试以上配置的切面是否在给定的切入点信息上执行。

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

import com.howtodoinjava.app.model.EmployeeDTO;
import com.howtodoinjava.app.service.EmployeeManager;

public class TestMain 
{
    @SuppressWarnings("resource")
    public static void main(String[] args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        EmployeeManager manager = (EmployeeManager) context.getBean("employeeManager");

        manager.getEmployeeById(1);
        manager.createEmployee(new EmployeeDTO());
    }
}

Method getEmployeeById() called

****LoggingAspect.logAfterAllMethods() : getEmployeeById
****LoggingAspect.logAfterGetEmployee() : getEmployeeById

Method createEmployee() called

****LoggingAspect.logAfterAllMethods() : createEmployee
****LoggingAspect.logAfterCreateEmployee() : createEmployee

显然,在相关联的关节上执行切面建议。

学习愉快!

参考文献:

Spring AOP 参考

@After注解

@Aspect注解

AspectJ 注解配置示例

不同切入点表达式示例