老项目迁移问题:@ImportResource导入的xml配置里的Bean能够使用@PropertySource导入的属性值吗?【享学Spring】(下)

简介: 老项目迁移问题:@ImportResource导入的xml配置里的Bean能够使用@PropertySource导入的属性值吗?【享学Spring】(下)

那么问题来了,为何使用PropertySourcesPlaceholderConfigurer,只需要简单的new一个就成了勒(并不需要手动设置location)?

一样的,从源码处一看便知,非常非常简单:


// @since 3.1  直接实现了EnvironmentAware,说明此Bean可以拿到当前环境Environment
public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerSupport implements EnvironmentAware {
  ...
  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    ...
    // 把环境属性都放进来~
    if (this.environment != null) {
      this.propertySources.addLast(
        new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) {
          @Override
          @Nullable
          public String getProperty(String key) {
            return this.source.getProperty(key);
          }
        }
      );
    }
    // 把配置的属性放进来~~~
    PropertySource<?> localPropertySource = new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());
    this.propertySources.addFirst(localPropertySource);
    ...
  } 
}


相信不用我做过多的解释,就知道为何不用自己设置location,直接使用注解@PropertySource("classpath:my.properties")就好使了吧。这个时候环境截图如下(注意:此处我截图是基于已经set了location的截图哦):


image.png


what?虽然配置时候set了location去加载属性文件,但是上面代码中add进去的属性源environmentProperties和localProperties


public static final String LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME = "localProperties";
public static final String ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME = "environmentProperties";


两个PropertySource都并没有出现?

关于此,我这里就不再解释了,哈哈。还是那句话,留给小伙伴们自己思考,若思考不明白的亦可扫码入群探讨哦~(当然参照上面文章也是可行的)


SpringBoot工程下使用


关于在SpringBoot中使用,简单到令人发指,毕竟SpringBoot的使命也是让你使用它能够简单到木有朋友。

so,在SpringBoot工程下使用@ImportResource和@PropertySource啥都不用配,它是能够天然的直接work的~


原因分析如下:

一切得益于SpringBoot强悍的自动化配置能力,它提供了这样一个配置类:

@Configuration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) // 最高优先级
public class PropertyPlaceholderAutoConfiguration {
  // 注意此处使用的是PropertySourcesPlaceholderConfigurer
  // 并且你可以在本容器内覆盖它的默认行为哟~~~~
  @Bean
  @ConditionalOnMissingBean(search = SearchStrategy.CURRENT)
  public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
  }
}


PropertyPlaceholderAutoConfiguration它被配置在了自动配置包下的spring.factories文件里:


# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
...
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
...


因此它会随着工程启动而自动生效。有了上面对Spring工程下的使用分析,此处就不用再花笔墨解释了~


另外附加说明一点:哪怕你的属性不使用@PropertySource导入,而是写在SB自带的application.properties文件里,依旧是没有问题的。

原因分析如下:

其实这个涉及到的是SpringBoot对application.properties的加载时机问题,因为本文对SB的介绍并不是重点,因此此处我直接简单的说出结论即止:


  • SpringBoot通过事件监听机制加载很多东西,加载此属性文件用的是ConfigFileApplicationListener这个监听器
  • 它监听到ApplicationEnvironmentPreparedEvent(环境准备好后)事件后开始加载application.properties等文件
  • ApplicationEnvironmentPreparedEvent的事件发出是发生在createApplicationContext()之前~~~ 部分代码如下:

public class SpringApplication {
  ...
  public ConfigurableApplicationContext run(String... args) {
    ...
    ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
    // 此步骤 会发出ApplicationEnvironmentPreparedEvent事件
    ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
    Banner printedBanner = printBanner(environment);
    // 开始创建,初始化容器~
    context = createApplicationContext();
    ...
  }
  ...
}


so,在SB环境下已经早早把属性都放进环境内了,借助它默认配置好的PropertySourcesPlaceholderConfigurer来处理的,那可不能正常work吗。一切都是这么自然,这或许就是SB的魅力所在吧~


关于小伙伴问题的解决


开头提出了问题,肯定得解决问题嘛~~~如下图


image.png

哈哈,虽然最终我并没有直接的帮助解决问题,但是此问题给了我写本文的动力,总体还是不错的~


总结


本文通过一个小伙伴咨询的小问题(真是小问题吗?)引申比较详细的说了Spring在处理占位符这块的内容(其实本并没打算写这么多的,尴尬~)

写本文的目的开头也说了,我认为在SpringBoot还并非100%渗透的当下,肯定有人会遇到从传统Spring项目向SpringBoot过度的一个阶段,而本文的描述或许能给你的迁移提供一种新的思路(特别是时间紧、任务重的时候),希望小伙伴们能有所收获,peace~

相关文章
|
9天前
|
前端开发 安全 Java
Spring Boot 便利店销售系统项目分包设计解析
本文深入解析了基于Spring Boot的便利店销售系统分包设计,通过清晰的分层架构(表现层、业务逻辑层、数据访问层等)和模块化设计,提升了代码的可维护性、复用性和扩展性。具体分包结构包括`controller`、`service`、`repository`、`entity`、`dto`、`config`和`util`等模块,职责分明,便于团队协作与功能迭代。该设计为复杂企业级应用开发提供了实践参考。
42 0
|
29天前
|
Java 测试技术 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
本课主要讲解Spring Boot项目中的属性配置方法。在实际开发中,测试与生产环境的配置往往不同,因此不应将配置信息硬编码在代码中,而应使用配置文件管理,如`application.yml`。例如,在微服务架构下,可通过配置文件设置调用其他服务的地址(如订单服务端口8002),并利用`@Value`注解在代码中读取这些配置值。这种方式使项目更灵活,便于后续修改和维护。
27 0
|
9天前
|
SQL 前端开发 Java
深入理解 Spring Boot 项目中的分页与排序功能
本文深入讲解了在Spring Boot项目中实现分页与排序功能的完整流程。通过实际案例,从Service层接口设计到Mapper层SQL动态生成,再到Controller层参数传递及前端页面交互,逐一剖析每个环节的核心逻辑与实现细节。重点包括分页计算、排序参数校验、动态SQL处理以及前后端联动,确保数据展示高效且安全。适合希望掌握分页排序实现原理的开发者参考学习。
33 4
|
11天前
|
Java Spring 容器
两种Spring Boot 项目启动自动执行方法的实现方式
在Spring Boot项目启动后执行特定代码的实际应用场景中,可通过实现`ApplicationRunner`或`CommandLineRunner`接口完成初始化操作,如系统常量或配置加载。两者均支持通过`@Order`注解控制执行顺序,值越小优先级越高。区别在于参数接收方式:`CommandLineRunner`使用字符串数组,而`ApplicationRunner`采用`ApplicationArguments`对象。注意,`@Order`仅影响Bean执行顺序,不影响加载顺序。
|
9天前
|
前端开发 IDE Java
Spring MVC 中因导入错误的 Model 类报错问题解析
在 Spring MVC 或 Spring Boot 开发中,若导入错误的 `Model` 类(如 `ch.qos.logback.core.model.Model`),会导致无法解析 `addAttribute` 方法的错误。正确类应为 `org.springframework.ui.Model`。此问题通常因 IDE 自动导入错误类引起。解决方法包括:删除错误导入、添加正确包路径、验证依赖及清理缓存。确保代码中正确使用 Spring 提供的 `Model` 接口以实现前后端数据传递。
34 0
|
9天前
|
SQL Java 编译器
深入理解 Spring Data JPA 的导入与使用:以 UserRepository为例
本文深入解析了 Spring Data JPA 中 `UserRepository` 的导入与使用。通过示例代码,详细说明了为何需要导入 `User` 实体类、`JpaRepository` 接口及 `@Repository` 注解。这些导入语句分别用于定义操作实体、提供数据库交互方法和标识数据访问组件。文章还探讨了未导入时的编译问题,并展示了实际应用场景,如用户保存、查询与删除操作。合理使用导入语句,可让代码更简洁高效,充分发挥 Spring Data JPA 的优势。
48 0
|
9天前
|
安全 前端开发 Java
Spring Boot 项目中触发 Circular View Path 错误的原理与解决方案
在Spring Boot开发中,**Circular View Path**错误常因视图解析与Controller路径重名引发。当视图名称(如`login`)与请求路径相同,Spring MVC无法区分,导致无限循环调用。解决方法包括:1) 明确指定视图路径,避免重名;2) 将视图文件移至子目录;3) 确保Spring Security配置与Controller路径一致。通过合理设定视图和路径,可有效避免该问题,确保系统稳定运行。
46 0
|
29天前
|
缓存 Java 应用服务中间件
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——依赖导入和Thymeleaf相关配置
在Spring Boot中使用Thymeleaf模板,需引入依赖`spring-boot-starter-thymeleaf`,并在HTML页面标签中声明`xmlns:th=&quot;http://www.thymeleaf.org&quot;`。此外,Thymeleaf默认开启页面缓存,开发时建议关闭缓存以实时查看更新效果,配置方式为`spring.thymeleaf.cache: false`。这可避免因缓存导致页面未及时刷新的问题。
41 0
|
29天前
|
Java 数据库 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——指定项目配置文件
在实际项目中,开发环境和生产环境的配置往往不同。为简化配置切换,可通过创建 `application-dev.yml` 和 `application-pro.yml` 分别管理开发与生产环境配置,如设置不同端口(8001/8002)。在 `application.yml` 中使用 `spring.profiles.active` 指定加载的配置文件,实现环境快速切换。本节还介绍了通过配置类读取参数的方法,适用于微服务场景,提升代码可维护性。课程源码可从 [Gitee](https://gitee.com/eson15/springboot_study) 下载。
51 0
|
29天前
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
在微服务架构中,随着业务复杂度增加,项目可能需要调用多个微服务。为避免使用`@Value`注解逐一引入配置的繁琐,可通过定义配置类(如`MicroServiceUrl`)并结合`@ConfigurationProperties`注解实现批量管理。此方法需在配置文件中设置微服务地址(如订单、用户、购物车服务),并通过`@Component`将配置类纳入Spring容器。最后,在Controller中通过`@Resource`注入配置类即可便捷使用,提升代码可维护性。
33 0