高級裝配用來適應開發和生產 不同環境下的軟切換
一、環境與PRofile
1.開發環境下的profile
package com.bonc.config;import javax.sql.DataSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Profile;import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;/* * 一、注解開發profile * @Profile作用在了類上,告訴Spring這個配置類中的bean只有在dev profile激活時才創建 * dev profile沒有被激活的話,@Bean的注解都會被忽略掉。 * * Spring3.1中,只能在類級別上使用@Profile注解,在Spring3.2開始, * 你也可以在方法級別上使用@Profile注解,與@Bean注解一同使用,這樣的話就能將兩個bean放置到同一個配置類中。 * * 盡管只有當規定的profile被激活時,相應的bean才會被創建,但是可能會有其他的bean并沒有聲明在一個給定的profile中。 * 沒有指定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.sql").build(); }}二、生產環境下profilepackage com.bonc.config;import javax.sql.DataSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Profile;import org.springframework.jndi.JndiObjectFactoryBean;@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(); }}三、在同一個類中配置開發與生產環境package com.bonc.config;import javax.sql.DataSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Profile;import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;import org.springframework.jndi.JndiObjectFactoryBean;@Configurationpublic class DataSourceConfig { @Bean(destroyMethod="shutdown") @Profile("dev") public DataSource embeddedDataSource(){ return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2) .addScript("classpath:schema.sql") .addScript("classpath:test.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配置各種環境<?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" 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-4.0.xsd"> <beans profile="dev"> <jdbc:embedded-database> <jdbc:script location="classpath:schema.sql"/> <jdbc:script location="classpath:test-data.sql"/> </jdbc:embedded-database> </beans> <beans profile="qa"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"/> </beans> <beans profile="prod"> <jee:jndi-lookup id="dataSource" jndi-name="jdbc/myDatabase" resource-ref="true" proxy-interface="javax.sql.DataSource"/> </beans><!-- 除了所有的bean定義到了同一個XML文件中,這種配置方式與定義在單獨的XML文件中的實際效果是一樣的。 這里有三個bean,類型都是javax.sql.DataSource, 并且ID都是dataSource。但是運行時,只會創建一個bean,這取決處于激活狀態的是那個profile --></beans>五、激活profile Spring在確定哪個profile處于激活狀態時,需要依賴兩個獨立的屬性;spring.profiles.active和 spring.profiles.default。如果設置了spring.profiles.active屬性的活,那么它的值就會用來確定是那個profile是激活的。如果沒有設置spring.profiles.active的屬性值,Spring將查找spring.profiles.default的值。如果兩者都沒設置,那就沒有激活的profile,只會創建那些沒有定義在profile中的值。有多種方式來設置這兩個屬性:1.作為DispatcherServlet的初始化參數
2.作為Web應用的上下文參數3.作為JNDI條目;4.作為環境變量5.作為JVM的系統屬性6.在集成測試類上,使用@ActiveProfiles注解設置。
比較推薦的是在web.xml配置 作為DispatcherServlet的初始化參數
<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name>spring learning</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/root-context.xml</param-value> </context-param> <context-param> <param-name>spring.profiles.default</param-name> <param-value>dev</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <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>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
新聞熱點
疑難解答