zoukankan      html  css  js  c++  java
  • Spring学习笔记-高级装配-03

    主要内容:

      ●Spring profile

      ●条件化的bean声明

      ●自动装配与歧义性

      ● Spring表达式语言

    本章介绍一些高级的装配技术,可实现更为高级的装配功能。

    环境与profile

    软件开发时,有一个很大的挑战就是讲应用程序从一个环境迁移到另外一个环境,开发环境可能并不适合迁移到生产环境,比如:数据库配置、加密算法以及外部系统的集成可能会发生变化。

    比如数据库配置:

      ● 在开发环境中可能使用的是嵌入式数据库,并预先加载测试数据,bean配置类可能会在一个带有@Bean注解的方法上使用EmbeddedDatabasebuilder(嵌入式数据源)。

      ● 在生产环境中可能使用JNDI从容器中获取一个DataSource。

      ● 在测试环境中可能选择另外一个不同的DataSource。

    在不同的还击某个bean因此不同,我们需要一种方法来配置DataSource,使其在不同环境中都会选择最合适的配置。

    配置profile

    Spring3.1版本中,引入了bean profile功能,要使用它,首先要将所有不同的bean定义整理到一个或多个profile中,在将应用部署到每个环境时,要确保对应的profile处于激活的状态。

    使用配置类配置profile

    在Java配置中,可使用@Profile注解指定某个bean属于哪一个profile,例如,在配置类中,

    嵌入式数据库的DataSource配置

    @Configuration
    @Profile("dev") //告诉Spring这个配置类的bean只有在dev profile激活时才会创建,如果dev profile没有激活那么带有@Bean注解的方法都会被忽略掉
    public class DevelopmentProfileConfig {
      @Bean
    public DataSource dataSource(){ return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .addScript("classppath:schema.sql") .addScript("classpath:test-data.sql") .build(); } }

    一个适用于生产环境的配置

    @Configuration
    @Profile("prod") //告诉Spring这个配置类的bean只有在prod profile激活时才会创建,如果dev profile没有激活那么带有@Bean注解的方法都会被忽略掉
    public class ProductionProfileConfig {
        @Bean
        public DataSource dataSource(){
            JndiObjectFactoryBean jndiObjectFactoryBean=
                    new JndiObjectFactoryBean();
            jndiObjectFactoryBean.setJndiName("jdbc/DS");
            jndiObjectFactoryBean.setResourceRef(true);
            jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
            return (DataSource) jndiObjectFactoryBean;
        }
    }

    在Spring中,只能在类级别上使用@Profile注解,不过从3.2版本开始,也可以再方法级别使用@Profile,这样的话就能和@Bean同时使用,同时将两个bean的声明放在同一个配置类中。

    @Profile注解基于激活的profile实现bean的装配

    @Configuration
    public class DataSourceProfile {
        @Bean
        @Profile("dev")  //为dev profile装配的bean
        public DataSource embededDataSource(){
            return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript("classppath:schema.sql")
                .addScript("classpath:test-data.sql")
                .build();
        }
        @Bean
        @Profile("prod") //为prod profile装配的bean
        public DataSource jndiDataSource(){
            JndiObjectFactoryBean jndiObjectFactoryBean=
                    new JndiObjectFactoryBean();
            jndiObjectFactoryBean.setJndiName("jdbc/DS");
            jndiObjectFactoryBean.setResourceRef(true);
            jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
            return (DataSource) jndiObjectFactoryBean;
        }
    }

    使用XML配置profile

    了解即可

    激活profile

    String在确定哪个profile处于激活状态时,需要依赖两个独立的属性:spring.profile.active和spring.profiles.default,如果设置了spring.profile.active属性,那么它的值就会用来确定哪个profile是激活的,如果没有设置,那就会查找spring.profiles.default的值,如果均没有设置那就没有激活的profile,则只会创建那些没用定义在profile中的bean。

    有多种方式来设置这两个属性:

    ● 作为DispatcherServlet的初始化参数;

    ● 作为Web应用的上下文参数;

    ●  作为JNDI条目;

    ● 作为环境变量;

    ● 作为JVM的系统属性;

    ● 在集成测试类上,使用@ActiveProfiles注解设置。

    在Web.xml文件中设置默认的profile

    <Web-app version="2.5">
        <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>    <!-- 为上下文设置默认的profile -->
            <param-value>dev</param-value>
        </context-param>
        
        <listener>
            <listent-class>
                org.springframework.web.context.ContextLoaderListener
            </listent-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> <!-- 为Servlet设置默认的profile -->
                <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>

     按照这种方式设置spring.profiles.default,所有开发文员都能才能够版本控制软件获得应用程序代码,并且使用开发环境的设置运行代码,而不需要任何额外设置。

    当程序部署到测试、生产或其他环境中,负责部署人员根据情况使用系统属性、环境变量或JNDI设置spring.profiles.active即可,此时spring.profiles.default值会被忽略,因为spring会优先使用spring.profiles.active的值。

    使用profile进行测试

    当集成运行测试时,通常会希望采用与生产环境相同的配置进行测试,但如果配置中的bean定义在profile中,那么在运行测试中,就需要有一种方式来启用合适的profile。

    Spring提供了@ActiveProfiles注解,我们可使用它指定运行测试时要激活那个Profile。在集成测试时,通常想要激活的是开发环境的profile,例如,下面的测试类片段展现如何使用@ActiveProfile激活dev profile:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextCOnfiguration(classes={PersistenceTestConfig.class})
    @ActiveProfiles("dev")
    public class ActiveProfileTest {
    ....

    条件化的Bean

      假设希望一个或多个bean只有在应用的类路径下包含特定的库时才会创建。或希望某个bean只有当另外某个特定的bean也声明后才会创建,以及等等需要满足各种条件才会创建。

    在Spring4引入了一个新的@Conditional注解,它可以用到带有@Bean注解的方法上,如果给定的条件计算结果为true,就会创建这个bean,否则就会被忽略。

    未完待续...

  • 相关阅读:
    POJ 1887 Testing the CATCHER
    HDU 3374 String Problem
    HDU 2609 How many
    POJ 1509 Glass Beads
    POJ 1458 Common Subsequence
    POJ 1159 Palindrome
    POJ 1056 IMMEDIATE DECODABILITY
    POJ 3080 Blue Jeans
    POJ 1200 Crazy Search
    软件体系结构的艺术阅读笔记1
  • 原文地址:https://www.cnblogs.com/vice/p/8761232.html
Copyright © 2011-2022 走看看