Spring高级杂记

简介: Spring高级杂记

后置处理器

在Spring框架中,后置处理器(Post-Processor)是一种常用的扩展机制,可以让开发者在Spring容器实例化Bean对象前后,对Bean对象进行自定义的处理。后置处理器是Spring框架中非常重要的一种机制,它可以在Bean对象实例化、初始化、销毁等过程中,介入Bean对象的生命周期,从而实现对Bean对象的定制化管理。

Spring框架中提供了很多后置处理器接口,比如BeanPostProcessor、InstantiationAwareBeanPostProcessor等等,开发者可以根据自己的需求实现这些接口,以实现自定义的Bean对象处理逻辑。例如,BeanPostProcessor接口中定义了两个方法:postProcessBeforeInitialization和postProcessAfterInitialization,可以让开发者在Bean对象实例化后,初始化前和初始化后,对Bean对象进行自定义处理。

后置处理器在Spring框架中应用广泛,常用于实现Bean对象的自动注入、AOP、事务管理等功能,可以大大简化开发者的工作。同时,后置处理器也是Spring框架的重要组成部分,对于深入理解Spring框架的工作原理和机制,也是必须了解的内容。

@PostConstruct注解

在Spring Boot中,@PostConstruct注解用于标记一个方法,该方法会在Bean对象创建后,且依赖注入完成后调用。它的作用类似于JavaEE中的@PostConstruct注解,用于在Bean对象初始化时执行一些初始化操作,例如数据加载、资源初始化等等。

具体来说,@PostConstruct注解的作用如下:

  1. 初始化Bean对象:@PostConstruct注解可以用于标记一个方法,在Bean对象创建后自动调用该方法,从而完成Bean对象的初始化工作。
  2. 注入依赖:@PostConstruct注解的方法会在依赖注入完成后调用,可以在该方法中访问依赖对象,完成一些需要依赖注入的操作。
  3. 简化初始化操作:使用@PostConstruct注解可以将Bean对象的初始化操作集中到一个方法中,使得代码更加简洁、可读性更高,并且避免了在构造函数中进行初始化操作的风险。

需要注意的是,@PostConstruct注解只能用于标记一个非静态、无参、并且返回void的方法,否则Spring容器将会抛出异常。此外,如果一个Bean对象中存在多个使用@PostConstruct注解标记的方法,那么它们的执行顺序是不确定的,因此不应该依赖于它们的执行顺序。如果需要有序执行多个初始化方法,可以使用@Order注解或者实现Ordered接口来指定执行顺序。

classpath*

classpath*:是Java中用于指定类路径的通配符,可以在指定类路径时匹配多个路径。在classpath*:路径中,classpath表示类路径,而*表示通配符,可以匹配多个路径。

在Java中,类路径是指Java虚拟机用于查找类和资源的路径。类路径可以包含多个目录和JAR文件,其中包含了Java应用程序需要的类和资源文件。classpath*则是一种特殊的类路径格式,它可以用于指定包含多个目录或JAR文件的类路径,从而在Java应用程序中查找类和资源文件时可以更加灵活。

在Spring框架中,classpath*:常常被用于指定Bean定义的扫描路径,从而自动扫描指定路径下的所有类并将其注册为Bean对象。通过使用classpath*,可以避免指定具体的文件名或路径,从而更加灵活地管理Bean对象。例如,可以使用如下代码指定Bean扫描路径:

@Configuration
@ComponentScan(basePackages = {"com.example.app"}, 
               includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {MyBean.class}),
               excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {MyExcludeBean.class}))
public class AppConfig {
    // ...
}

在上面的代码中,@ComponentScan注解使用了classpath*:指定Bean扫描路径为com.example.app,同时还包含了一个包含过滤器和一个排除过滤器。其中,包含过滤器指定只扫描MyBean类,排除过滤器指定不扫描MyExcludeBean类。通过这种方式,可以精确控制Bean扫描范围,从而实现更加灵活的配置管理。

@Bean(initMethod = "init")

@Bean(initMethod = "init")中的initMethod是一个可选的属性,它指定了一个在Bean初始化完成后需要被调用的初始化方法的名称。这个方法必须没有参数,返回类型可以是任意类型,如果有任何异常抛出,Spring容器将捕获并记录它们,但不会重新抛出。

当一个bean被创建时,Spring容器会首先创建一个实例对象,然后填充所有的属性值,最后调用初始化方法来完成一些其他的初始化工作。如果你不指定initMethod属性,Spring容器会默认调用Java类中的无参构造方法作为初始化方法。

以下是一个示例:

@Component
public class MyBean {
    public void init() {
        // 在这里执行bean的初始化工作
    }
}

在这个例子中,MyBean类中定义了一个名为init()的初始化方法,这个方法会在MyBean对象被创建完成后被自动调用。如果你使用了@Bean(initMethod = "init")注解来声明MyBean对象的创建,Spring容器会在MyBean对象被创建完成后调用init()方法来完成一些其他的初始化工作。

refresh()方法

在 Spring 容器启动时,会调用 refresh() 方法来加载所有的 Bean 定义,并创建 Bean 实例。在应用程序运行期间,如果需要动态更新 Bean 定义或者刷新容器状态,可以再次调用 refresh() 方法。

refresh() 方法的主要执行过程包括以下几个步骤:

  1. 创建 BeanFactory,加载 Bean 定义;
  2. 对 Bean 定义进行解析和验证;
  3. 注册 BeanPostProcessor;
  4. 实例化非懒加载的单例 Bean,并执行 BeanPostProcessor 的前置和后置处理方法;
  5. 实例化懒加载的单例 Bean,并执行 BeanPostProcessor 的前置和后置处理方法;
  6. 发布容器事件;
  7. 启动容器中的所有定时任务。

总的来说,refresh() 方法是 Spring 容器启动和初始化的核心方法,它确保所有的 Bean 定义都被正确加载,并创建了相应的 Bean 实例。

@Lazy

Spring 中的 @Lazy 注解可以用来控制 Bean 的创建时机。默认情况下,Spring 容器会在启动时就实例化所有的单例(Singleton)Bean,即所谓的“饥饿实例化”。如果我们的应用中存在很多单例 Bean,这样的做法可能会导致启动时间变慢。

使用 @Lazy 注解,可以将 Bean 的创建时机推迟到第一次使用时。当一个 Bean 被标记了 @Lazy 注解后,它会在第一次被使用时才被创建,而不是在 Spring 容器启动时立即创建。这种方式称为“懒加载”。

@Lazy 注解可用于类、字段和方法上。当用于类上时,表示将该类声明为懒加载 Bean;当用于字段上时,表示该字段是一个懒加载的依赖项;当用于方法上时,表示该方法返回的对象是一个懒加载 Bean。

使用 @Lazy 注解可以有效地减少启动时间和资源消耗,尤其是对于那些占用大量资源或者需要较长时间初始化的 Bean。但需要注意的是,懒加载可能会导致在第一次使用时出现较长的等待时间,因为 Bean 的初始化和依赖注入可能需要较长时间,还有如果懒加载的 Bean 在容器中被多个线程同时访问,可能会导致线程安全问题,需要进行相应的处理。

目录
相关文章
|
6月前
|
存储 缓存 Java
【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践
【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践
|
6月前
|
前端开发 搜索推荐 Java
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革
|
6月前
|
Java 测试技术 数据库连接
【Spring源码解读!底层原理高级进阶】【下】探寻Spring内部:BeanFactory和ApplicationContext实现原理揭秘✨
【Spring源码解读!底层原理高级进阶】【下】探寻Spring内部:BeanFactory和ApplicationContext实现原理揭秘✨
|
5月前
|
前端开发 Java 开发者
深入理解 Spring Boot 注解:核心功能与高级用法详解
深入理解 Spring Boot 注解:核心功能与高级用法详解
310 1
|
6月前
|
存储 安全 Java
第10章 Spring Security 的未来趋势与高级话题(2024 最新版)(下)
第10章 Spring Security 的未来趋势与高级话题(2024 最新版)
90 2
|
6月前
|
安全 Cloud Native Java
第10章 Spring Security 的未来趋势与高级话题(2024 最新版)(上)
第10章 Spring Security 的未来趋势与高级话题(2024 最新版)
77 2
|
6月前
|
数据采集 前端开发 Java
数据塑造:Spring MVC中@ModelAttribute的高级数据预处理技巧
数据塑造:Spring MVC中@ModelAttribute的高级数据预处理技巧
68 3
|
6月前
|
XML Java 数据格式
进阶注解探秘:深入Spring高级注解的精髓与实际运用
进阶注解探秘:深入Spring高级注解的精髓与实际运用
71 2
|
6月前
|
Java 关系型数据库 MySQL
高级对象装配:解析Spring创建复杂对象的秘诀
高级对象装配:解析Spring创建复杂对象的秘诀
58 0
高级对象装配:解析Spring创建复杂对象的秘诀
|
6月前
|
安全 Java UED
第5章 Spring Security 的高级认证技术(2024 最新版)(下)
第5章 Spring Security 的高级认证技术(2024 最新版)
57 0