老项目迁移问题:@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~

目录
打赏
0
0
0
0
36
分享
相关文章
【SpringFramework】Spring IoC-基于XML的实现
本文主要讲解SpringFramework中IoC和DI相关概念,及基于XML的实现方式。
117 69
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
46 7
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
本文介绍了在使用Spring框架时,如何通过创建`applicationContext.xml`配置文件来管理对象。首先,在resources目录下新建XML配置文件,并通过IDEA自动生成部分配置。为完善配置,特别是添加AOP支持,可以通过IDEA的Live Templates功能自定义XML模板。具体步骤包括:连续按两次Shift搜索Live Templates,配置模板内容,输入特定前缀(如spring)并按Tab键即可快速生成完整的Spring配置文件。这样可以大大提高开发效率,减少重复工作。
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
【Spring项目】表白墙,留言板项目的实现
本文主要介绍了表白墙项目的实现,包含前端和后端代码,以及测试
【Spring】——SpringBoot项目创建
SpringBoot项目创建,SpringBootApplication启动类,target文件,web服务器,tomcat,访问服务器
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
75 6
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
83 2
Spring MVC——项目创建和建立请求连接
MVC是一种软件架构设计模式,将应用分为模型、视图和控制器三部分。Spring MVC是基于MVC模式的Web框架,通过`@RequestMapping`等注解实现URL路由映射,支持GET和POST请求,并可传递参数。创建Spring MVC项目与Spring Boot类似,使用`@RestController`注解标记控制器类。
65 1
Spring MVC——项目创建和建立请求连接
Maven——创建 Spring Boot项目
Maven 是一个项目管理工具,通过配置 `pom.xml` 文件自动获取所需的 jar 包,简化了项目的构建和管理过程。其核心功能包括项目构建和依赖管理,支持创建、编译、测试、打包和发布项目。Maven 仓库分为本地仓库和远程仓库,远程仓库包括中央仓库、私服和其他公共库。此外,文档还介绍了如何创建第一个 SpringBoot 项目并实现简单的 HTTP 请求响应。
341 1
Maven——创建 Spring Boot项目

热门文章

最新文章