SpringBoot中使用aop-测试

面向切面编程(AOP),该种方式主要是为了弥补面向对象编程(OOP)的不足,通过配置切面以及关注点、通知等我们可以在程序的任意位置对我们的代码进行增强(执行一些代码),AOP是Spring的特性之一,通常我们使用AOP来实现日志的补记录以及实现一些声明式的事务等。

接下来,通过一个简单的例子来测试一下AOP如何使用:

1、pom.xml文件的依赖如下

<dependencies>
        <!--1.单元测试的依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--2.aop的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!--3.cglib动态代理的依赖-->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.5</version>
        </dependency>
        <!--4.web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--5.小辣椒-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

2、application.yml(springboot)的配置文件内容如下:

  其中,server.port代表端口号(tomcat的端口号)

  其他内容为自定义的内容,可通过@Value注解获取到内容值

  ${name}为使用表达式获取当前yml文件中对应的name的值

3、定义用于返回的类(使用RestController,返回json数据),代码如下:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
    private boolean success;
    private String msg;
}

4、定义自己的Service类(模拟业务场景),代码如下:

@Service
public class JieService {

    public void todo(){
        System.out.println("这是一个Service方法的调用!");
    }
}

  @Service :把该类注入Spring容器中,若需要使用,则通过@Autowired 注解获取

5、定义一个Controller类(控制类,模拟处理用户的请求),代码如下:

@RestController
public class JieController {
    @Autowired
    private JieService jieService;
    // 使用yml配置文件中的参数
    @Value("${content}")
    public String content;

    @RequestMapping("/hello")
    public Result hello(){
        jieService.todo();
        return new Result(true,content);
    }
}

  其中,@Autowired 注解则获取到Spring容器中我们通过@Service 注解注入的对象

  @RestController 注解为标记返回的数据为json格式

  @Value 注解则获取到application.yml 文件中对应的参数名的值,这里@Value(${content})的写法跟在yml中去到定义的值一样

6、配置一个切面类,且注入Spring容器中,通过@Aspect 标记为切面类、@Component 注入Spring容器中,并且添加一些测试方法,代码如下:

@Component  // 注册到spring容器中
@Aspect // 标志为切面类
public class ServiceAdvice {
    /**
     * 解读:
     *      execution为固定写法
     *      public * com.jieku.service..*.*(..)
     *      第一个 * 表示所有的返回参数
     *      之后代表切入点的包名,其后跟着两个点(.)表示当前包及其所有的子包
     *      两个点后的* 代表所有的类   =》 综合两个点加上*   ..* 表示当前包及其所有子包的所有类
     *      之后的点个人理解为调用方法,点后的*表示所有的方法,之后括号中的两个点.表示任意的参数个数
     *      总的解答:拦截com.jieku.service的当前包及其子包中的所有类(任意的返回参数类型)的所有方法的调用(任意参数列表)
     */
    @Pointcut("execution(public * com.jieku.service..*.*(..))")
    public void good(){}

    @Before("good()")
    public void before(){
        System.out.println("之前拦截到了,并且执行了!");
    }

    @After("good()")
    public void after(){
        System.out.println("之后也拦截到了,并且执行了!");
    }

    /**
     * @Ponitcut:表示切入点,理解为找到需要增强的方法执行我们定义的增强的代码
     * 通知:
     * @Before:前置通知,方法执行前执行该通知
     * @After:后置通知,方法执行完成之后执行该通知
     * @Around:环绕通知
     * @AfterReturning:在返回之后执行该通知
     * @AfterThrowing:在抛出异常后执行该通知
     */
}

7、执行效果如下:

  在页面上输入:localhost:8080/hello,执行效果如下:

8、补充:启动类以及项目结构图

启动类代码如下:

@SpringBootApplication
public class JieApplication {
    public static void main(String[] args) {
        SpringApplication.run(JieApplication.class);
    }
}

项目结构图如下:

9、后台的运行结果:

 

至此,简单测试成功!

posted @ 2019-11-26 10:22  koooin  阅读(1318)  评论(0编辑  收藏  举报