• spring Environment


    Environment
    环境在容器中是一个抽象的集合,是指应用环境的2个方面: profiles和 properties.

    profile
    配置是一个被命名的,bean定义的逻辑组,这些bean只有在给定的profile配置激活时才会注册到容器。不管是XML还是注解,Beans都有可能指派给profile配置。Environment环境对象的作用,对于profiles配置来说,它能决定当前激活的是哪个profile配置,和哪个profile是默认。

    在所有的应用中,Properties属性扮演一个非常重要的角色,可能来源于一下源码变量:properties文件,JVM properties,system环境变量,JNDI, servlet context parameters上下文参数,专门的Properties对象,Maps等等。Environment对象的作用,对于properties来说,是提供给用户方便的服务接口,方便撰写配置、方便解析配置。

    bean定义profiles是核心容器内的一种机制,该机制能在不同环境中注册不同的bean。环境的意思是,为不同的用户做不同的事儿,该功能在很多场景中都非常有用,包括:开发期使用内存数据源,在QA或者产品上则使用来自JNDI的相同的数据源开发期使用监控组件,当部署以后则关闭监控组件,是应用更高效为用户各自注册自定义bean实现.

    考虑一个实际应用中的场景,现在需要一个DataSource。开测试环境中,这样配置:

    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.HSQL)
            .addScript("my-schema.sql")
            .addScript("my-test-data.sql")
            .build();
    }
    

      

    现在想一想,如何将应用部署到QA或者生产环境,假设生产环境中使用的JNDI。我们的dataSource bean看起来像这样:

    @Bean(destroyMethod="")
    public DataSource dataSource() throws Exception {
        Context ctx = new InitialContext();
        return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
    }
    

      

    我们需要在某些上下文环境中使用某些bean,在其他环境中则不用这些bean。你也许会说,你需要在场景A中注册一组bean定义,在场景B中注册另外一组。先看看我们如何修改配置来完成此需求。
    @Profile注解的作用,是在一个或者多个指定profiles激活的情况下,注册某个组件。使用上面的样例,重写dataSource配置:

    @Configuration
    @Profile("dev")
    public class StandaloneDataConfig {
    
        @Bean
        public DataSource dataSource() {
            return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.HSQL)
                .addScript("classpath:com/bank/config/sql/schema.sql")
                .addScript("classpath:com/bank/config/sql/test-data.sql")
                .build();
        }
    }
    @Configuration
    @Profile("production")
    public class JndiDataConfig {
    
        @Bean(destroyMethod="")
        public DataSource dataSource() throws Exception {
            Context ctx = new InitialContext();
            return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
        }
    }
    

      

    开启profile

    要修改配置,我们仍然需要指定要激活哪个文件。如果现在运行上面的样例应用,它会抛异常NoSuchBeanDefinitionException,因为容器找不到dataSourcebean。

    有多种方式激活配置,但是最直接的方式是编程式的方式使用ApplicationContext API

    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.getEnvironment().setActiveProfiles("dev");
    ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class);
    ctx.refresh();
    

      

    此外,还可以使用spring.profiles.active激活配置,该属性可以配置在系统环境变量、JVM系统属性、web.xml
    中JNDI中的servlet context上下文参数
    注意配置文件不是单选;可能会同时激活多个配置文件,编程式的使用方法setActiveProfiles(),该方法接收String数组参数,也就是多个配置文件名

    ctx.getEnvironment().setActiveProfiles("profile1", "profile2");
    //声明式的使用spring.profiles.active ,值可以为逗号分隔的配置文件名列表, -Dspring.profiles.active="profile1,profile2"

     

    如果没有任何profile配置被激活,默认的profile将会激活。
    默认profile配置文件可以更改,通过环境变量的setDefaultProfiles方法,或者是声明的spring.profiles.default属性值

    Spring的环境抽象提供了用于检索一系列的property sources属性配置文件。

    ApplicationContext ctx = new GenericApplicationContext();
    Environment env = ctx.getEnvironment();
    boolean containsFoo = env.containsProperty("foo");
    System.out.println("Does my environment contain the ''foo'' property? " + containsFoo);
    

      

    在上面的片段中,通过较高层次方式检索SPring是否在当前环境中定义了foo property属性。为了检索该属性,环境对象在一组PropertySource对象中执行检索。PropertySource是key-value键值对配置文件的抽象,Spring的StandardEnvironment
    配置了2个PropertySource对象.其一是JVM系统properties(System.getProperties()),另一个是一组系统环境变量System.getEnv()。

    @PropertySource注解提供了一个方便的方式,用于增加一个PropertySource到Spring的环境中: 给定一个文件"app.properties"包含了key/value键值对testbean.name=myTestBean,下面的@Configuration类使用了@PropertySource
    ,使用这种方式调用testBean.getName()将会返回myTestBean。

    @Configuration
    @PropertySource("classpath:/com/myco/app.properties")
    public class AppConfig {
        @Autowired
        Environment env;
    
        @Bean
        public TestBean testBean() {
            TestBean testBean = new TestBean();
            testBean.setName(env.getProperty("testbean.name"));
            return testBean;
        }
    }
    

      

    转自:https://www.jianshu.com/p/49e950b0b008

  • 相关阅读:
    FZU OJ 1056 :扫雷游戏
    HPU 1166: 阶乘问题(一)
    常用的一些模板
    PAT天梯:L1-019. 谁先倒
    HPU 1437: 王小二的求值问题
    《编程珠玑》阅读小记(7) — 代码调优与节省空间
    《编程珠玑》阅读小记(6) — 算法设计技术
    《编程珠玑》阅读小记(5) — 编程小事
    《编程珠玑》阅读小记(4) — 编写正确的程序
    《C/C++专项练习》— (1)
  • 原文地址:https://www.cnblogs.com/itplay/p/10736340.html
Copyright © 2020-2023  润新知