基于注解的AOP实现

  Spring AOP允许使用基于注解的方式实现AOP,这样做可以简化Spring配置文件的臃肿代码。


表1 Spring AOP提供的一系列注解

元素

描述

@Aspect

配置切面

@Pointcut

配置切点

@Before

配置前置通知

@After

配置后置通知

@Around

配置环绕方式

@AfterReturning

配置返回通知

@AfterThrowing

配置异常通知

  了解了如何使用注解配置切面、切入点和通知后,下面通过一个案例演示基于注解的AOP的实现,案例具体实现步骤如下。
  (1)在chapter07项目(自己在IDEA中新建一个)的pom.xml文件中导入AspectJ框架相关JAR包的依赖,在pom.xml中添加的代码如下:

<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjrt</artifactId>
	<version>1.9.1</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.6</version>
</dependency>

  (2)在chapter07项目的src/main/java目录下创建一个com.cqust.dao包,在该包下创建接口UserDao,并在该接口中编写添加、删除、修改和查询的方法。UserDao接口具体代码如下:

package com.cqust.dao;

public interface UserDao {
    public void insert();
    public void delete();
    public void update();
    public void select();
}

  (3)在com.cqust.dao包下创建UserDao接口的实现类UserDaoImpl,实现UserDao接口中的方法。

package com.cqust.dao;

public class UserDaoImpl implements UserDao{
    public void insert(){
        System.out.println("添加用户信息");
    }
    public void delete(){
        System.out.println("删除用户信息");
    }
    public void update(){
        System.out.println("更新用户信息");
    }
    public void select(){
        System.out.println("查询用户信息");
    }
}

  (4)com.cqust.dao包下创建AnnoAdvice类,用于定义通知。

package com.cqust.dao;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

@Aspect
public class AnnoAdvice {
    //切点
    @Pointcut("execution( * com.cqust.dao.UserDaoImpl.*(..))")
    public void poincut(){}
    //前置通知
    @Before("poincut()")
    public void before(JoinPoint joinPoint){        //使用JoinPoint接口实例作为参数获得目标对象的类名和方法名
        System.out.print("这是前置通知!");
        System.out.print("目标类:" + joinPoint.getTarget());
        System.out.println(",被织入增强处理的目标方法为:"+joinPoint.getSignature().getName());
    }
    //返回通知
    @AfterReturning("poincut()")
    public void afterReturning(JoinPoint joinPoint){//使用JoinPoint接口实例作为参数获得目标对象的类名和方法名
        System.out.print("这是返回通知(方法不出现异常时调用)!");
        System.out.println("被织入增强处理的目标方法为:"+joinPoint.getSignature().getName());
    }
    /**
     * 环绕通知
     * ProceedingJoinPoint是JoinPoint子接口,表示可以执行目标方法
     * 1.必须是Object类型的返回值
     * 2.必须接收一个参数,类型为ProceedingJoinPoint
     * 3.必须throws Throwable
     */
    @Around("poincut()")
    public Object around(ProceedingJoinPoint point)throws Throwable{//使用ProceedingJoinPoint接口实例作为参数获得目标对象的类名和方法名
        System.out.println("这是环绕通知之前的部分!");
        //调用目标方法
        Object object = point.proceed();
        System.out.println("这是环绕通知之前的部分!");
        return object;
    }
    //异常通知
    @AfterThrowing("poincut()")
    public void afterException(){
        System.out.println("异常通知!");
    }
    //后置通知
    @After("poincut()")
    public void after(){
        System.out.println("这是后置通知!");
    }
}

  需要注意的是,环绕通知必须接收一个类型为ProceedingJoinPoint的参数,返回值也必须是Object类型,且必须抛出异常。
  (5)在chapter07项目的src/main/java目录下创建一个applicationContext.xml文件,在该文件中引入AOP命名空间,使用< bean >元素添加Spring AOP的配置信息。

<?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.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 注册Bean -->
    <bean name="userDao" class="com.cqust.dao.UserDaoImpl"/>
    <bean name="AnnoAdvice" class="com.cqust.dao.AnnoAdvice"/>
    <!-- 开启@aspectj的自动代理支持 -->
    <aop:aspectj-autoproxy/>

</beans>

  (6)在src/test/java目录下创建测试类TestAnnotation。

import com.cqust.dao.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAnnotation {
    public static void main(String[] args){
        ApplicationContext context = new
                ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = context.getBean("userDao",UserDao.class);
        userDao.delete();
        System.out.println();
        userDao.insert();
        System.out.println();
        userDao.select();
        System.out.println();
        userDao.update();
    }
}

在IDEA中启动TestAnnotation类,控制台的输出结果如图所示。

java 对象中 bool 限制 注解 java aop注解实现_java 对象中 bool 限制 注解

  由运行结果可知,程序执行了AnnoAdvice类中的增强方法,表明Spring AOP实现了对目标对象的方法增强。

谢谢浏览!