zoukankan      html  css  js  c++  java
  • spring引用properties文件

    问题场景:开发环境发生变化,原先环境下的相关做法可能需要进行改变。常见的比如:数据库配置、算法或者和外部环境集成。比如配置数据库:EmbeddedDatabaseBuiler搭建一个Hypersonic数据库,或者使用JNDI从容器中获取一个DataSource,或者使用Commons DBCP连接池,他们都虽然都返回一个javax.sql.DataSource的Bean,但是都是用了不同的策略。

    所以不同环境中的Bean会有所不同,必须用一种方式来配置DataSource,使其在每种环境下都采用最合适的配置。

    spring的解决方法

    spring可以使用Bean profile功能,spring在运行时期,采用Bean profile决定创建哪一个bean,不创建哪一个bean,而不是构建时期。要实现这个效果要做到两点:
    1. 确保不同的bean定义和整理到一个或多个profile中
    2. 确保需要创建bean时,对应的profile处于激活状态

    通过Profile创建Bean

    有两种方式,一种是使用JavaConfig进行配置,一种是使用XML文件进行配置。其中JavaConfig的配置又可以分成基于类的配置和基于方法的配置。

    JavaConfig通过@Profile创建Bean

    通过JavaConfig创建需要用到@Profile注解,一种是将注解注释在类上,一种是将注解注释到方法上。区别在于注释在方法上可以将两个Bean放在一个类里面,如下:

    @Profile写在类上

    @Configuration
      @Profile("dev")
      public class DevelopmentProfileConfig{
    
        @Bean(destroyMethod = "shutdown")
          public DataSource dataSource() {
            return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript("classpath:schema.sql")
                .addScript("classpath:test-data.sql")
                .build();
          }
       }
    
    @Configuration
      @Profile("prod")
      public class ProductionProfileConfig{
    
        @Bean
          public DataSource dataSource() {
                JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
                jndiObjectFactoryBean.setJndiName("jdbc/myDS");
                jndiObjectFactoryBean.setResourceRef(true);
                jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
                return (DataSource) jndiObjectFactoryBean.getObject();
          }
       }

    @Profile写在方法上

    @Configuration
    public class DataSourceConfig {
    
      @Bean(destroyMethod = "shutdown")
      @Profile("dev")
      public DataSource embeddedDataSource() {
        return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.H2)
            .addScript("classpath:schema.sql")
            .addScript("classpath:test-data.sql")
            .build();
      }
    
      @Bean
      @Profile("prod")
      public DataSource jndiDataSource() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("jdbc/myDS");
        jndiObjectFactoryBean.setResourceRef(true);
        jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
        return (DataSource) jndiObjectFactoryBean.getObject();
      }
    
    }

    XML中进行配置

    使用 <beans profile="">

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
      xmlns:jee="http://www.springframework.org/schema/jee" xmlns:p="http://www.springframework.org/schema/p"
      xsi:schemaLocation="
        http://www.springframework.org/schema/jee
        http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/jdbc
        http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
      <beans profile="dev">
        <jdbc:embedded-database id="dataSource" type="H2">
          <jdbc:script location="classpath:schema.sql" />
          <jdbc:script location="classpath:test-data.sql" />
        </jdbc:embedded-database>
      </beans>
    
      <beans profile="prod">
        <jee:jndi-lookup id="dataSource"
          lazy-init="true"
          jndi-name="jdbc/myDatabase"
          resource-ref="true"
          proxy-interface="javax.sql.DataSource" />
      </beans>
    </beans>

    激活Profile

    看上面的XML文件中,可以看到两个Bean的ID都是datasource,创建bean的时候只会创建一个DataSource,创建哪一个就看哪一个Profile被激活了。

    spring有两种方式查看哪一个profile处于激活状态,他们分别是:
    1. spring.profiles.default
    2. spring.profiles.active
    第二个的优先级高于第一个的优先级,所以可以默认使用DispatcherServlet参数将spring.profiles.default设置为默认参数,当部署到新环境中,可以使用系统属性、环境变量或JNDI设置spring.profiles.active

    web.xml配置默认profile

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
             version="2.5">
        <display-name>testCache</display-name>
    
        <context-param>
            <!-- 为上下文设置默认profile -->
            <param-name>spring.profile.default</param-name>
            <param-value>dev</param-value>
        </context-param>
    
        <filter>
            <filter-name>encodingFilter</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>encodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
    
        <servlet>
            <servlet-name>springServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>/WEB-INF/spring-mvc.xml</param-value>
                <!-- 为Servlet设置默认的profile -->
                <param-name>spring.profiles.default</param-name>
                <param-value>dev</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>springServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    
        <session-config>
            <session-timeout>30</session-timeout>
        </session-config>
    </web-app>

    @ActiveProfiles(“dev”)注解激活dev测试

    @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(classes=DataSourceConfig.class)
      @ActiveProfiles("dev")
      public static class DevDataSourceTest {
        @Autowired
        private DataSource dataSource;
    
        @Test
        public void shouldBeEmbeddedDatasource() {
          assertNotNull(dataSource);
          JdbcTemplate jdbc = new JdbcTemplate(dataSource);
          List<String> results = jdbc.query("select id, name from Things", new RowMapper<String>() {
            @Override
            public String mapRow(ResultSet rs, int rowNum) throws SQLException {
              return rs.getLong("id") + ":" + rs.getString("name");
            }
          });
    
          assertEquals(1, results.size());
          assertEquals("1:A", results.get(0));
        }
      }
  • 相关阅读:
    INFORMIX体系效能改善第一步
    Ubuntu判袂率不正常的一种复杂治理措施
    ubuntu8.04分区分配方案
    计算机启动更快的十五招
    理顺 JavaScript (13) 对象及 json
    获取指定地址的 JPG 图片 回复 "bangrj" 的问题
    理顺 JavaScript (14) constructor 与 instanceof
    理顺 JavaScript (9) Date 类
    用 API 提取、写入指定网站的 Cookie 回复 "bangrj" 的问题
    理顺 JavaScript (10) Math 类
  • 原文地址:https://www.cnblogs.com/shuiyj/p/13185254.html
Copyright © 2011-2022 走看看