zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Android 按键消息处理Android 按键消息处理
    objcopy
    SQLite多线程读写实践及常见问题总结
    android动画坐标定义
    Android动画效果translate、scale、alpha、rotate
    Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)
    Flatten Binary Tree to Linked List
    Distinct Subsequences
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
  • 原文地址:https://www.cnblogs.com/itplay/p/10736340.html
Copyright © 2011-2022 走看看