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));
        }
      }
  • 相关阅读:
    为图片指定区域添加链接
    数值取值范围问题
    【leetcode】柱状图中最大的矩形(第二遍)
    【leetcode 33】搜索旋转排序数组(第二遍)
    【Educational Codeforces Round 81 (Rated for Div. 2) C】Obtain The String
    【Educational Codeforces Round 81 (Rated for Div. 2) B】Infinite Prefixes
    【Educational Codeforces Round 81 (Rated for Div. 2) A】Display The Number
    【Codeforces 716B】Complete the Word
    一个简陋的留言板
    HTML,CSS,JavaScript,AJAX,JSP,Servlet,JDBC,Structs,Spring,Hibernate,Xml等概念
  • 原文地址:https://www.cnblogs.com/shuiyj/p/13185254.html
Copyright © 2011-2022 走看看