注入或手动获取配置(IOC)
约定:
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
注入相关注解:
@Inject,注入。可注解目标:字段,方法参数,类(配置类),方法(@Bean方法)@BindProps,绑定属性。可注解目标:类(配置类),方法(@Bean方法)。//可以生成配置提示
如何配置参考:
1、如何通过注入获得配置?
- 注入到字段
 
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
@Component
public class DemoService{
    //注入值(带默认值:demoApi),并开启自动更新(注意:如果不是单例,请不要开启自动刷新)
    @Inject(value="${track.name:demoApi}", autoRefreshed=true)
    static String trackName; //v3.0 后支持静态字段注入
    
    //注入值(没有时,不覆盖字段初始值)
    @Inject("${track.url}")
    String trackUrl = "http://x.x.x/track";
    
    //注入配置集合
    @Inject("${track.db1}")
    Properties trackDbCfg;
    
    //注入Bean(根据对应的配置集合自动生成并注入)
    @Inject("${track.db1}")
    HikariDataSource trackDs;
}
- 注入到一个配置类或实体类(之后可复用)
 
import org.noear.solon.annotation.BindProps;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
//@Inject("${classpath:user.config.yml}")  //也可以注入一个配置文件 
@Inject("${user.config}")  
@Configuration
public class UserProperties{
    public String name;
    public List<String> tags;
    ...
}
@BindProps(prefix="user.config")  //或者用绑定属性注解。v3.0.7 后支持
@Configuration
public class UserProperties{
    public String name;
    public List<String> tags;
    ...
}
@Configuration
public class DemoConfig {
    @BindProps(prefix="user.config") //或者用绑定属性注解。v3.0.7 后支持
    @Bean
    public UserProperties userProperties(){
        return new UserProperties();
    }
}
//别处,可以注入复用
@Inject
UserProperties userProperties;
- 注入到 
@Bean方法的参数(不支持自动刷新) 
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Condition;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
import org.noear.solon.data.cache.CacheService;
@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(onExpression="${cache.enable:false} == true") //有 "cache.enable" 属性值,且等于true
    public CacheService cache(@Inject("${cache.config}") CacheServiceSupplier supper){
       return supper.get();
    }
}
- 注入到组件的构造参数(即,构造函数注入)
 
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
@Component
public class DemoConfig{
    private String demoName;
    
    public DemoConfig(@Inject("${deom.name}") String name) {
        this.demoName = name;
    }
}
2、如何手动获得配置?
- 给字段赋值
 
import org.noear.solon.Solon;
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);
}
- 用方法时实获取最新态(建议不要获取复杂的对象,避免构建的性能浪费)
 
import org.noear.solon.Solon;
public class DemoService{
    //获取值(带默认值:demoApi)
    public static String trackName(){
        return Solon.cfg().get("track.name", "demoApi");
    }
    
    //获取值
    public static String trackUrl(){
        return Solon.cfg().get("track.url");
    }
}
- 构建Bean给配置器用
 
import org.noear.solon.Solon;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
@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、配置的自动刷新与手动订阅变更
- 自动刷新
 
"自动刷新"只适合于字段注入,以及单例的类。(注意:如果不是单例,请不要开启自动刷新)
import org.noear.solon.Solon;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
@Component
public class DemoService{
    //注入值(带默认值:demoApi),并开启自动更新
    @Inject(value="${track.name:demoApi}", autoRefreshed=true)
    String trackName;
    
    //通过函数时时获取最新的(静态或动态,按需设定)
    public static String trackName2(){
        return Solon.cfg().get("track.name:demoApi");
    }
}
- 手动订阅变更
 
这个接口会订阅所有变更的key,需要自己过滤处理:
import org.noear.solon.Solon;
Solon.cfg().onChange((key,val)->{
    if(key.startsWith("track.name")){ // "track.name" 表示前缀
        //...
    }
});