springboot2原理实战(17)--aop开发必知必会

简介: springboot2原理实战(17)--aop开发必知必会

目录


本文的主要内容如下:

1dc618a0ed9580ce8bfa6facb208c08f.png


一、使用aop小demo认识开发流程


1:spring-boot-start-aop 加入依赖,默认开启了Aop的支持


 

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>


写个被切入的类:


@Repository
public class UserDao {
    public void add(String username, String password){
        System.out.println("add 【username:"+username+",password:"+password+"】");
    }
}


2:写一个Aspect,封装横切关注点(日志,监控等待),需要配置前置通知,后置通知等待,和切入点,哪些包的哪些类的方法等等


这个Aspect需要@Component纳入到spring容器管理,并且需要纳入spring管理:


@Aspect

@Component
public class LogAspect {
    @Before("execution(* com.springboot.demo17.dao..*.*(..))")
    public void log(){
//        System.out.println("before method log done "+ AopContext.currentProxy().getClass());
        System.out.println("before method log done");
    }
 }


3.测试:


@SpringBootApplication
public class Demo17Application {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Demo17Application.class, args);
        System.out.println(context.getBean(UserDao.class).getClass());
        context.getBean(UserDao.class).add("admin","123");
        context.close();
    }


运行结果:


5d4c6812c8535adbb050f4ddf2e1bce8.png

显示aop已经生效。


二、了解springboot的代理和切换代理操作


看下aop自动配置的类:

46a9d80a6e05e4e3b19d57a0ee70bcdf.png


通过源码,我们可以看到,


1.spring.aop", name = “auto”, havingValue = “true”,说明springboot默认为我们开启Aop我们可以通过这个spring.auto来设置是否开启关闭。


2.springboot2默认是使用的cglib代理。我们可以使用spring.aop.proxy-target-class的true和fasle,来切换代理模式是cglib还是jdk动态代理。true代表cglib,false代表jdk动态代理。


1.默认的动态代理cglib


刚才的aop入门小demo的控制台打印看下:

1dc618a0ed9580ce8bfa6facb208c08f.png

这里也说明我们的确是使用的cglib


2.切换成jdk动态代理


我们知道jdk动态代理是面向接口的,现在设置下:


写一个接口:


public interface IuserDao {
    public void add(String username, String password);
}


@Repository


public class UserDao implements IuserDao{
    public void add(String username, String password){
        System.out.println("add 【username:"+username+",password:"+password+"】");
    }
}


配置文件修改动态代理方式:


spring.aop.auto=true
spring.aop.proxy-target-class=false


打印查看:


@SpringBootApplication
public class Demo17Application {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Demo17Application.class, args);
        System.out.println(context.getBean(UserDao.class).getClass());
        //
        context.getBean(UserDao.class).add("admin","123");
        context.close();
    }
}


测试类:


@SpringBootApplication
public class Demo17Application {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Demo17Application.class, args);
        //得用接口获取对象
        System.out.println(context.getBean(IuserDao.class).getClass());
        context.getBean(IuserDao.class).add("admin","123");
        context.close();
    }
}


运行,控制台打印:


1dc618a0ed9580ce8bfa6facb208c08f.png

显示已经是java的jdk动态代理了。


特别注意: UserDao必须实现个IUserDao的接口,必须通过接口获取实例,不然使用的还是cglib动态代理。


三、使用aop获取切面参数


拿到切面里面的类或者参数,可以通过JoinPoint point

5d4c6812c8535adbb050f4ddf2e1bce8.png

这里有上面几个方法,可以通过getTarget获取类,getArgs获取方法的参数,getSignature().获取方法名称。


测试下:


改下编织类,添加个after后置织入:


@Aspect
@Component
public class LogAspect {
    @Before("execution(* com.springboot.demo17.dao..*.*(..))")
    public void log(){
//        System.out.println("before method log done "+ AopContext.currentProxy().getClass());
        System.out.println("before method log done");
    }
    @After("execution(* com.springboot.demo17.dao..*.*(..))")
    public void logAfter(JoinPoint point){
        System.out.println("after method log done"+point.getTarget().getClass()+",args="+ Arrays.asList(point.getArgs())+",method="+point.getSignature().getName());
    }
}


测试:


@SpringBootApplication
public class Demo17Application {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Demo17Application.class, args);
        System.out.println(context.getBean(UserDao.class).getClass());
        //
        context.getBean(UserDao.class).add("admin","123");
        context.close();
    }
}


运行入口函数,控制台打印:


1dc618a0ed9580ce8bfa6facb208c08f.png

显示切面里面的类和参数和方法名都已经获取到了。


四、EnableAspectJAutoProxy获取代理对象


看下这个类的源码:

5d4c6812c8535adbb050f4ddf2e1bce8.png


有2个属性:


proxyTargetClass: 这个属性也可以切换动态代理方式,true代表cglib,false是jdk动态代理


exposeProxy: 这个属性设置为true可以获取到代理对象是谁。

设置为true,可以获取到AopContext对象:

1dc618a0ed9580ce8bfa6facb208c08f.png


现在测试下:

修改织入类:


@Aspect
@Component
public class LogAspect {
    @Before("execution(* com.springboot.demo17.dao..*.*(..))")
    public void log(){
        System.out.println("before method log done "+ AopContext.currentProxy().getClass());
        System.out.println("before method log done");
    }
 }


入口函数,设置可获取代理对象:@EnableAspectJAutoProxy(exposeProxy = true):


@EnableAspectJAutoProxy(exposeProxy = true)
@SpringBootApplication
public class Demo17Application {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Demo17Application.class, args);
        System.out.println(context.getBean(UserDao.class).getClass());
        //
        context.getBean(UserDao.class).add("admin","123");
        context.close();
    }
}


运行,控制台打印如下:


5d4c6812c8535adbb050f4ddf2e1bce8.png

可以看到,代理对象是:EnhancerBySpringCGLIB.


本文,主要讲laop如何使用,如何切换动态代理,如何拿到动态代理的参数,如何获取代理对象。


相关文章
|
1月前
|
XML Java 开发者
Spring Boot中的AOP实现
Spring AOP(面向切面编程)允许开发者在不修改原有业务逻辑的情况下增强功能,基于代理模式拦截和增强方法调用。Spring Boot通过集成Spring AOP和AspectJ简化了AOP的使用,只需添加依赖并定义切面类。关键概念包括切面、通知和切点。切面类使用`@Aspect`和`@Component`注解标注,通知定义切面行为,切点定义应用位置。Spring Boot自动检测并创建代理对象,支持JDK动态代理和CGLIB代理。通过源码分析可深入了解其实现细节,优化应用功能。
|
3月前
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
57 0
|
28天前
|
XML Java 应用服务中间件
Spring Boot 两种部署到服务器的方式
本文介绍了Spring Boot项目的两种部署方式:jar包和war包。Jar包方式使用内置Tomcat,只需配置JDK 1.8及以上环境,通过`nohup java -jar`命令后台运行,并开放服务器端口即可访问。War包则需将项目打包后放入外部Tomcat的webapps目录,修改启动类继承`SpringBootServletInitializer`并调整pom.xml中的打包类型为war,最后启动Tomcat访问应用。两者各有优劣,jar包更简单便捷,而war包适合传统部署场景。需要注意的是,war包部署时,内置Tomcat的端口配置不会生效。
211 17
Spring Boot 两种部署到服务器的方式
|
28天前
|
Dart 前端开发 JavaScript
springboot自动配置原理
Spring Boot 自动配置原理:通过 `@EnableAutoConfiguration` 开启自动配置,扫描 `META-INF/spring.factories` 下的配置类,省去手动编写配置文件。使用 `@ConditionalXXX` 注解判断配置类是否生效,导入对应的 starter 后自动配置生效。通过 `@EnableConfigurationProperties` 加载配置属性,默认值与配置文件中的值结合使用。总结来说,Spring Boot 通过这些机制简化了开发配置流程,提升了开发效率。
61 17
springboot自动配置原理
|
2月前
|
Java 数据库连接 Maven
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
自动装配是现在面试中常考的一道面试题。本文基于最新的 SpringBoot 3.3.3 版本的源码来分析自动装配的原理,并在文未说明了SpringBoot2和SpringBoot3的自动装配源码中区别,以及面试回答的拿分核心话术。
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
|
1月前
|
存储 安全 Java
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
82 8
|
2月前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
153 14
|
3月前
|
监控 安全 Java
什么是AOP?如何与Spring Boot一起使用?
什么是AOP?如何与Spring Boot一起使用?
111 5
|
3月前
|
Java 开发者 Spring
Spring AOP 底层原理技术分享
Spring AOP(面向切面编程)是Spring框架中一个强大的功能,它允许开发者在不修改业务逻辑代码的情况下,增加额外的功能,如日志记录、事务管理等。本文将深入探讨Spring AOP的底层原理,包括其核心概念、实现方式以及如何与Spring框架协同工作。
|
3月前
|
Java Spring
SpringBoot自动装配的原理
在Spring Boot项目中,启动引导类通常使用`@SpringBootApplication`注解。该注解集成了`@SpringBootConfiguration`、`@ComponentScan`和`@EnableAutoConfiguration`三个注解,分别用于标记配置类、开启组件扫描和启用自动配置。
79 17