Solon

一、注入或手动获取配置(IOC)

</> markdown

约定

resources/app.yml( 或 app.properties ) #为应用配置文件

配置样例

track:
  name: xxx
  url: http://a.a.a
  db1:
    jdbcUrl: "jdbc:mysql://..."
    username: "xxx"
    password: "xxx"

配置注入的表达式

  • ${xxx} 注入属性
  • ${xxx:def} 注入属性,如果没有提供 def 默认值。 //只支持单值接收(不支持集合或实体)
  • ${classpath:xxx.yml} 注入资源目录下的配置文件 xxx.xml

1、如何通过注入获得配置?

  • 注入到字段
@Component
public class DemoService{
    //注入值(带默认值:demoApi),并开启自动更新(注意:如果不是单例,请不要开启自动刷新)
    @Inject(value="${track.name:demoApi}", autoRefreshed=true)
    String trackName;
    
    //注入值(没有时,不覆盖字段初始值)
    @Inject("${track.url}")
    String trackUrl = "http://x.x.x/track";
    
    //注入配置集合
    @Inject("${track.db1}")
    Properties trackDbCfg;
    
    //注入Bean(根据对应的配置集合自动生成并注入)
    @Inject("${track.db1}")
    HikariDataSource trackDs;
}
  • 注入到一个配置类或实体类(之后可复用)
//@Inject("${classpath:user.config.yml}")  //也可以注入一个配置文件 
@Inject("${user.config}")  
@Configuration
public class UserConfig{
    public String name;
    public List<String> tags;
    ...
}

//别处,可以注入复用
@Inject
UserConfig userConfig;

@Configuration
public class DemoConfig{
    @Bean
    public void demo(@Inject UserConfig userConfig);
}
  • 注入到配置器的构建参数(与注入字段的方式差不多)
@Configuration
public class DemoConfig{
    //提示:@Bean 只能与 @Configuration 配合
    @Bean 
    public DataSource db1(@Inject("${track.db1}") HikariDataSource ds) {
        return ds;
    }
    
    @Bean
    public DataSourceWrap db1w(@Inject DataSource ds, @Inject("${wrap}") WrapConfig wc) {
        return new DataSourceWrap(ds, wc);
    }
    
    //也可以带条件处理
    @Bean
    @Condition(onProperty="${cache.enable} = true") //有 "cache.enable" 属性值,且等于true
    public CacheService cache(@Inject("${cache.config}") CacheServiceSupplier supper){
       return supper.get();
    }
}

2、如何手动获得配置?

  • 给字段赋值
public class DemoService{
    //获取值(带默认值:demoApi)
    static String trackName = Solon.cfg().get("track.name", "demoApi");
    //获取值
    static String trackUrl = Solon.cfg().get("track.url");
    
    //获取配置集合
    Properties trackDbCfg = Solon.cfg().getProp("track.db1");
    //获取bean(根据配置集合自动生成)
    HikariDataSource trackDs = Solon.cfg().getBean("track.db1", HikariDataSource.class);
}
  • 构建Bean给配置器用
@Configuration
public class DemoConfig{
    @Bean
    public DataSource db1() {
        return Solon.cfg().getBean("track.db1", HikariDataSource.class);
    }
    
    @Bean
    public DataSourceWrap db1w(@Inject DataSource ds) {
        WrapConfig wc = Solon.cfg().getBean("wrap", WrapConfig.class);
        
        return new DataSourceWrap(ds, wc);
    }
}

3、配置的自动刷新与手动订阅变更

  • 自动刷新

"自动刷新"只适合于字段注入,以及单例的类。(注意:如果不是单例,请不要开启自动刷新)

@Component
public class DemoService{
    //注入值(带默认值:demoApi),并开启自动更新
    @Inject(value="${track.name:demoApi}", autoRefreshed=true)
    String trackName;
}
  • 手动订阅变更

这个接口会订阅所有变更的key,需要自己过滤处理:

Solon.cfg().onChange((key,val)->{
    if(key.startsWith("track.name")){ // "track.name" 表示前缀
        //...
    }
});