• Spring aop使用


    前言:aop即Aspect Oriented-Programming,面向切面编程是对面向对象编程思想的补充,在众多的aop资料介绍中,我推荐大家可查看Spring Aop详尽教程Spring Aop实例

    我这里主要通过实例来简单介绍Spring aop在Springboot中的使用及自己踩的小坑

    1. 搭建springboot环境,直接附上一份pom.xml配置文件,此份文件结合了Mybatis+mysql


    4.0.0

    <groupId>com.jing.sprintboot</groupId>
    <artifactId>TestSpringBoot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    
    <name>TestSpringBoot</name>
    <url>https://mvnrepository.com</url>
    <properties>
    	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    	<spring.version>4.2.3.RELEASE</spring.version>
    	<spring.boot.version>1.3.0.RELEASE</spring.boot.version>
    	<tomcat.version>8.0.28</tomcat.version>
    </properties>
    
    <parent>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-parent</artifactId>
    	<version>1.3.0.RELEASE</version>
    </parent>
    <dependencies>
    	<dependency>
    		<groupId>junit</groupId>
    		<artifactId>junit</artifactId>
    		<version>3.8.1</version>
    		<scope>test</scope>
    	</dependency>
    	<dependency>
    		<groupId>javax.servlet</groupId>
    		<artifactId>javax.servlet-api</artifactId>
    		<version>3.1.0</version>
    		<scope>provided</scope><!-- 编译需要而发布不需要的jar包 -->
    	</dependency>
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-web</artifactId>
    		<version>${spring.boot.version}</version>
    	</dependency>
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-freeMarker</artifactId>
    		<version>1.3.0.RELEASE</version>
    	</dependency>
    	<!-- mybatis -->
    	<dependency>
    		<groupId>org.mybatis.spring.boot</groupId>
    		<artifactId>mybatis-spring-boot-starter</artifactId>
    		<version>1.1.1</version>
    	</dependency>
    	<!-- mysql -->
    	<dependency>
    		<groupId>mysql</groupId>
    		<artifactId>mysql-connector-java</artifactId>
    	</dependency>
    </dependencies>
    <build>
    	<plugins>
    		<plugin>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-maven-plugin</artifactId>
    			<version>${spring.boot.version}</version>
    			<executions>
    				<execution>
    					<goals>
    						<goal>repackage</goal>
    					</goals>
    				</execution>
    			</executions>
    		</plugin>
    	</plugins>
    	<defaultGoal>compile</defaultGoal>
    </build>
    
    ```
    
    1. 添加aop环境,主要是添加aspectjweaver.jar依赖

      <!-- aop -->
      	<dependency>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-starter-aop</artifactId>
      	</dependency>
      
      
    2. aop示例代码如下:

      package com.jing.springboot.aop;
      
      import org.aspectj.lang.ProceedingJoinPoint;
      import org.aspectj.lang.annotation.After;
      import org.aspectj.lang.annotation.AfterReturning;
      import org.aspectj.lang.annotation.Around;
      import org.aspectj.lang.annotation.Aspect;
      import org.aspectj.lang.annotation.Before;
      import org.aspectj.lang.annotation.Pointcut;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.stereotype.Component;
      
      @Aspect
      @Component
      public class RequestAopInterceptor {
          private static final Logger REQ_LOGGER = LoggerFactory.getLogger(RequestAopInterceptor.class);
      
      // 匹配语法为:注解 修饰符 返回值类型 类名 方法名(参数列表) 异常列表 具体可查看
      // http://blog.csdn.net/wangpeng047/article/details/8556800
      @Pointcut("execution(* com.jing.springboot.controller..*(..)) and @annotation(org.springframework.web.bind.annotation.RequestMapping)")
      public void interceptor() {
      
      }
      
      // 指定声明的pointcut
      @Before("interceptor()")
      public void before() {
      	REQ_LOGGER.info("before the requestMapping");
      }
      
      @After("interceptor()")
      public void after() {
      	REQ_LOGGER.info("requestMapping is over");
      }
      
      @AfterReturning(pointcut = "interceptor()", returning = "result")
      public void doAfterReturing(Object result) {
      	REQ_LOGGER.info("请求返回的信息为: " + result);
      }
      
      @Around("interceptor()")
      public Object doRound(ProceedingJoinPoint joinPoint) {
      	Object result = null;
      	REQ_LOGGER.info("doRound before");
      	try {
      		result = joinPoint.proceed();
      	} catch (Throwable e) {
      		e.printStackTrace();
      	}
      	REQ_LOGGER.info("doRound after");
      	return result;
      }
      

    }
    ```

    1. 注意@Around注解,其返回值是Object,不可写为void,不然将会导致前台获取数据不得的情况
    2. 罗列下Spring aop中的@Before@After@AfterReturning@AfterThrowing@Around的执行顺序
      • @Around前半部分
      • @Before代码逻辑
      • @Around后半部分
      • @After代码逻辑
      • @AfterReturing/@AfterThrowing代码逻辑,前者是在正确返回时触发,后者在出现异常时触发,其中的触发条件也可根据参数来指定,具体可见前言的链接博客
    3. 回到示例,写个Hello World
      package com.jing.springboot.controller;
      
      import javax.annotation.Resource;
      
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestMethod;
      import org.springframework.web.bind.annotation.RestController;
      import org.springframework.web.servlet.ModelAndView;
      
      import com.jing.springboot.model.Person;
      import com.jing.springboot.mysql.mapper.UserDao;
      
      
      //@author jingsir
      @RestController
      @RequestMapping(value = "/hello")
      public class HelloWorldControl {
      
      @Resource
      private UserDao userDao;
      
      public HelloWorldControl() {
      }
      
      @RequestMapping(value = "", method = RequestMethod.GET)
      public Person returnPerson() {
      	Person person = new Person();
      	person.setName("jingtj");
      	person.setAge(23);
      	return person;
      }
      
      //可测试@AfterReturning的返回值参数
      @RequestMapping(value = "/", method = RequestMethod.GET)
      public String hello() {
      	return "hello world";
      }
      
      //此段可忽略
      @RequestMapping(value = "/freemarker")
      public ModelAndView helloFreemaker() {
      	ModelAndView indexView = new ModelAndView("index");
      	indexView.addObject("user", "jingsir");
      	return indexView;
      }
      

    }

    ```
    * 其中在application.properties的配置信息如下:
    ```
    

    server.port=9901
    server.contextPath=/springboot
    * 浏览器访问localhost:9901/springboot/hello/便可,查看后台控制台的内容为(对照上述的第五点执行顺序便可明白):
    2017-03-19 20:25:44.074 INFO 502 --- [nio-9901-exec-3] c.j.s.aop.RequestAopInterceptor : doRound before
    2017-03-19 20:25:44.074 INFO 502 --- [nio-9901-exec-3] c.j.s.aop.RequestAopInterceptor : before the requestMapping
    2017-03-19 20:25:44.074 INFO 502 --- [nio-9901-exec-3] c.j.s.aop.RequestAopInterceptor : doRound after
    2017-03-19 20:25:44.074 INFO 502 --- [nio-9901-exec-3] c.j.s.aop.RequestAopInterceptor : requestMapping is over
    2017-03-19 20:25:44.074 INFO 502 --- [nio-9901-exec-3] c.j.s.aop.RequestAopInterceptor : doAfterReturing-->请求返回的信息为: hello world
    ```

    作者:南柯问天 出处:http://www.cnblogs.com/question-sky/ 本文版权归本人和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    SQL学习(一)之简介
    Mysql学习(三)之数据库管理工具Navicat
    Mysql学习(二)之安装、开启自启、启动、重启、停止
    Mysql学习(一)之简单介绍
    Mysql学习(二)之通过homebrew安装mysql后,为什么在系统偏好设置里没有mysql
    Git复习(十三)之git revert用法及与git reset区别
    Git复习(十二)之命令专场
    PE笔记之节
    PE文件格式---节和节表
    PE笔记之NT头PE扩展头
  • 原文地址:https://www.cnblogs.com/question-sky/p/6582105.html
Copyright © 2020-2023  润新知