专栏名称: ImportNew
伯乐在线旗下账号,专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等。
目录
相关文章推荐
芋道源码  ·  为什么有些程序员上班时总是戴着耳机? ·  17 小时前  
芋道源码  ·  手把手教你实现一个Java Agent ·  17 小时前  
芋道源码  ·  我用这11招,让接口性能提升了100倍 ·  2 天前  
51好读  ›  专栏  ›  ImportNew

深入 Spring Boot : 那些注入不了的 Spring 占位符(${} 表达式)

ImportNew  · 公众号  · Java  · 2017-07-29 12:00

正文

请到「今天看啥」查看全文


  • 处理BeanFactoryPostProcessor

  • 实例化Bean

  • 处理Bean的property注入

  • 处理BeanPostProcessor


  • 当然这只是比较理想的状态,实际上因为Spring Context在构造时,也需要创建很多内部的Bean,应用在接口实现里也会做自己的各种逻辑,整个流程会非常复杂。


    那么占位符(${}表达式)是在什么时候被处理的?


    1. 实际上是在org.springframework.context.support.PropertySourcesPlaceholderConfigurer里处理的,它会访问了每一个bean的BeanDefinition,然后做占位符的处理;

    2. PropertySourcesPlaceholderConfigurer实现了BeanFactoryPostProcessor接口;

    3. PropertySourcesPlaceholderConfigurer的 order是Ordered.LOWEST_PRECEDENCE,也就是最低优先级的。


    结合上面的Spring的生命周期,如果Bean的创建和使用在PropertySourcesPlaceholderConfigurer之前,那么就有可能出现占位符没有被处理的情况。


    例子1:Mybatis 的 MapperScannerConfigurer引起的占位符没有处理


    例子代码: mybatis-demo.zip


    https://github.com/hengyunabc/hengyunabc.github.io/files/1158339/mybatis-demo.zip


    首先应用自己在代码里创建了一个DataSource,其中${db.user}是希望从application.properties里注入的。代码在运行时会打印出user的实际值。


    @Configuration

    public class MyDataSourceConfig {

    @Bean(name = "dataSource1")

    public DataSource dataSource1(@Value("${db.user}") String user) {

    System.err.println("user: " + user);

    JdbcDataSource ds = new JdbcDataSource();

    ds.setURL("jdbc:h2:˜/test");

    ds.setUser(user);

    return ds;

    }

    }


    然后应用用代码的方式来初始化mybatis相关的配置,依赖上面创建的DataSource对象


    @Configuration

    public class MybatisConfig1 {

    @Bean(name = "sqlSessionFactory1")

    public SqlSessionFactory sqlSessionFactory1(DataSource dataSource1) throws Exception {

    SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

    org.apache.ibatis.session.Configuration ibatisConfiguration = new org.apache.ibatis.session.Configuration();

    sqlSessionFactoryBean.setConfiguration(ibatisConfiguration);

    sqlSessionFactoryBean.setDataSource(dataSource1);

    sqlSessionFactoryBean.setTypeAliasesPackage("sample.mybatis.domain");

    return sqlSessionFactoryBean.getObject();







    请到「今天看啥」查看全文