Spring完整揭秘(六):使用maven建立Spring AOP 的完整案例

项目工程

Spring完整揭秘(六):使用maven建立Spring AOP 的完整案例_第1张图片

导入依赖

  • 首先新建一个maven项目,在项目的pom.xml中添加spring相关及AOP的依赖项:

<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.0modelVersion>

    <groupId>springgroupId>
    <artifactId>aopdemoartifactId>
    <version>1.0-SNAPSHOTversion>

    <properties>
        <spring.version>5.2.2.RELEASEspring.version>
    properties>

    <dependencies>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-coreartifactId>
            <version>${spring.version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>${spring.version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-aopartifactId>
            <version>${spring.version}version>
        dependency>
        <dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjrtartifactId>
            <version>1.6.12version>
        dependency>
        <dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjweaverartifactId>
            <version>1.6.12version>
        dependency>
        <dependency>
            <groupId>cglibgroupId>
            <artifactId>cglibartifactId>
            <version>2.2version>
        dependency>
    dependencies>

project>
注入目标
  • 新建一个用户类User及用户服务类UserService,是我们AOP注入的目标类:
  • Service类中定义了2个方法,增加用户addUser方法,删除用户deleteUser方法并抛出运行时的异常。
/**
 * 用户类
 */
public class User {
    private String name;
    private String password;

    public User() {
    }

    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public String getName() {
        return name;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "demo.aop.User{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

/**
 * 用户服务类
 */
@Service
public class UserService {
    /**
     * 增加用户
     */
    public void addUser(User user) {
        System.out.println("增加用户:"+user.toString());
    }
	 /**
     * 删除用户
     */
    public void deleteUser(User user){
        System.out.println("删除用户:"+user.toString());
        throw new RuntimeException("edit person throw exception");
    }

}

Aspect类

  • Aspect类中定义pointCut()方法,此方法无任何执行内容,只有一个@Pointcut的注解,其他方法都会引用这个注解中指定的pointcut表达式。
  • 该类中还包括了各种Advice类型的方法实现,且都可以通过JoinPoint实例来获得方法执行的上下文信息,参数信息。
/**
 * aop组件
 */
@Aspect
@Component
public class AspectComponent {

    @Pointcut("execution(* demo.aop.*Service*.*(..))")
    public void pointCut(){

    }

    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
        System.out.println("before aspect executed"+joinPoint.toString());
    }

    @After("pointCut()")
    public void after(JoinPoint joinPoint) {
        System.out.println("after aspect executed:"+joinPoint.toString());
    }


    @AfterReturning(pointcut = "pointCut()", returning = "returnVal")
    public void afterReturning(JoinPoint joinPoint, Object returnVal) {
        System.out.println("afterReturning executed, return result is "
                + returnVal +joinPoint.toString());
    }

    @Around("pointCut()")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around start");
        try {
            pjp.proceed();
        } catch (Throwable ex) {
            System.out.println("error in around");
            throw ex;
        }
        System.out.println("around end");
    }

    @AfterThrowing(pointcut = "pointCut()", throwing = "error")
    public void afterThrowing(JoinPoint joinPoint, Throwable error) {
        System.out.println("error:" + error+joinPoint.toString());
    }
}

Spring配置

  • beans节点中需要指定aop命名空间
  • 启用aop需要添加aop:aspectj-autoproxy/
  • context:component-scan/节点用来指定自动扫描bean的命名空间。

<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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">
    <aop:aspectj-autoproxy />
    <context:component-scan base-package="demo.aop" />
beans>

测试

  • 测试下aop的效果,需要新建一个Application类作为程序的入口:

/**
 * aop测试程序
 */
public class Application {
    public static void main(String[] args) {

        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");

        // 测试用户服务aop过程
        UserService userService=ctx.getBean(UserService.class);
        User user = new User("jack","123456");
        userService.addUser(user);
        System.out.println("======================================================================");
        userService.deleteUser(user);

        ctx.close();
    }
}
  • 观察执行结果可以看到:执行的Before,around,after以及around,afterReturning,afterThrowing都按正常的顺序执行。
    Spring完整揭秘(六):使用maven建立Spring AOP 的完整案例_第2张图片

你可能感兴趣的:(spring,java,java,spring)