• (026)Spring Boot之aop


      aop即面向切面的编程,将业务逻辑代码和琐碎逻辑代码分开,达到重用或者解耦的目的。springboot中添加完依赖即默认启用了aop。

      starter-aop依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>

      贴出完整pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <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.edu.spring</groupId>
        <artifactId>springboot_web</artifactId>
        <version>1.0.0</version>
    
        <name>springboot_web</name>
        <!-- FIXME change it to the project's website -->
        <url>http://www.example.com</url>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.4.RELEASE</version>
        </parent>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
        </dependencies>
    
    </project>
    View Code

      springboot中aop有两个配置:spring.aop.auto和spring.aop.proxy-target-class,请看源码:

      spring.aop.auto默认是true,默认启动aop。

      spring.aop.proxy-target-class默认是true,默认使用cglib动态代理。

      (一)基于jdk的动态代理实现,必须同时满足两个条件

      (1)application.properties文件中设置spring.aop.proxy-target-class=false

    spring.aop.proxy-target-class=false

      (2)必须有接口类

      IUserDao.java

    package com.edu.spring.springboot;
    
    public interface IUserDao {
        public void add(String username,String password);
    }
    View Code

      UserDao.java

    package com.edu.spring.springboot;
    
    import org.springframework.stereotype.Component;
    
    @Component
    public class UserDao implements IUserDao {
    
        public void add(String username,String password){
            System.out.println("add [username="+username+",password="+password+"]");
        }
    }
    View Code

      LogAspect.java,使用@Aspect、@Before、@After注解

    package com.edu.spring.springboot;
    
    import java.util.Arrays;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class LogAspect {
    
        @Before("execution(* com.edu.spring.springboot..*.*(..))")
        public void log(){
            System.out.println("before method log done");
        }
        
        @After("execution(* com.edu.spring.springboot..*.*(..))")
        public void afterLog(JoinPoint point){
            System.out.println("after method log done "+point.getTarget().getClass()+",args: "+Arrays.asList(point.getArgs())+", method: "+point.getSignature());
        }
    }
    View Code

      App.java

    package com.edu.spring.springboot;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.ConfigurableApplicationContext;
    
    @SpringBootApplication
    public class App    
    { 
        public static void main(String[] args) throws Exception{
            ConfigurableApplicationContext context=SpringApplication.run(App.class, args); 
            System.out.println(context.getBean(IUserDao.class).getClass());
            context.getBean(IUserDao.class).add("sl","1234");
            context.close();
        }
    } 
    View Code

      运行结果如下:

      (二)基于cglib的动态代理实现。可以使用接口,也可以不用接口,spring.aop.proxy-target-class=true或者去掉该配置,运行结果如下:

       说明:LogAspect是切面类,封装了横切关注点,使用@Aspect标记,并且装配到spring容器中。

        @Before是前置通知,调用add方法前先执行

        @After是后置通知,调用完add方法后执行

        参数execution(* com.edu.spring.springboot..*.*(..))表示该包(或者其子包)下的任何类中的任何方法都会被动态代理。

        JoinPoint类中封装了被代理的对象,包括目标类、方法、参数。前置通知、后置通知都可以使用JoinPoint。

  • 相关阅读:
    mysql——mysql各个集群方案 (转)
    Actor——调度器Dispatcher
    记录的好处
    复习
    mysql中的weekofyear,yearweek函数的使用
    安吉丽娜朱莉访问乌克兰
    https://blog.csdn.net/weixin_35917052/article/details/116995151
    时间数列
    这些点赞的比较多
    Mysql锁类型分析
  • 原文地址:https://www.cnblogs.com/javasl/p/11966667.html
Copyright © 2020-2023  润新知