高级装配用来适应开发和生产 不同环境下的软切换

一、环境与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();
    }
}

二、生产环境下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.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;

@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.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>
												

【Spring 核心】高级装配的更多相关文章

  1. 【Spring】高级装配

    前言 前面讲解了bean的核心装配技术,其可应付很多中装配情况,但Spring提供了高级装配技术,以此实现更为高级的bean装配功能. 高级装配 配置profile bean 将所有不同bean定义放 ...

  2. 【Spring 核心】装配bean(二) JavaConfig装配

    前面介绍完了组件扫描和自动装配,这里再来看一下装配bean的另一种方式JavaConfig. 包路径: src/main/java com.bonc-|--config--|--CDPlayerCon ...

  3. 【Spring 核心】装配bean(三)XML配置

    项目包结构: src/main/java com.bonc.pojo--|-CompactDisc.java (接口) |-SgtPeppers.java     (实现类 实现 CompactDis ...

  4. 【Spring 核心】装配Bean(一) 自动化装配

    Spring从两个角度实现自动化装配:组件扫描 (Spring自动发现应用上下文中所创建的bean)自动装配(autowiring)自动满足bean之间的依赖 组件扫描: package test.s ...

  5. Spring 之高级装配

    [环境与Profile] 暂略 [条件化的bean] 暂略 [处理自动装配歧义性] 暂略 [ bean 的作用域] 在 @Componen . @Bean 下以及 XML 中的声明方式如下所示, @C ...

  6. Spring高级装配

    Spring高级装配 目录 一.Profile(根据开发环境创建对应的bean) 二.条件化的创建bean(根据条件创建bean) 三.处理自动装配歧义性(指定首选bean.限定符限制bean) 四. ...

  7. Spring使用笔记(三) 高级装配

    高级装配 一.环境与Profile 一)配置profile bean 环境的改变导致配置改变(需求:通过环境决定使用哪个bean),可以通过Spring的Profile解决. Profile可以在程序 ...

  8. Spring高级装配(一) profile

    Spring高级装配要学习的内容包括: Spring profile 条件化的bean声明 自动装配与歧义性 bean的作用域 Spring表达式语言 以上属于高级一点的bean装配技术,如果你没有啥 ...

  9. spring学习总结——高级装配学习二(处理自动装配的歧义性)

    我们已经看到如何使用自动装配让Spring完全负责将bean引用注入到构造参数和属性中.自动装配能够提供很大的帮助.不过,spring容器中仅有一个bean匹配所需的结果时,自动装配才是有效的.如果不 ...

随机推荐

  1. JavaScript中异步编程

    一 关于事件的异步 事件是JavaScript中最重要的一个特征,nodejs就是利用js这一异步而设计出来的.所以这里讲一下事件机制. 在一个js文件中,如果要运行某一个函数,有2中手段,一个就是直 ...

  2. ES6解构赋值

    前面的话 我们经常定义许多对象和数组,然后有组织地从中提取相关的信息片段.在ES6中添加了可以简化这种任务的新特性:解构.解构是一种打破数据结构,将其拆分为更小部分的过程.本文将详细介绍ES6解构赋值 ...

  3. sudo 和su

    场景:在服务器上进行操作的时候通常不适用root用户,但是有时候执行某一些操作需要使用root权限... 1 su命令 使用su命令来切换用户,su是switch user切换用户的缩写. 可以是从普 ...

  4. Experience of Python Learning Week 1

    1.The founder of python is Guido van Rossum ,he created it on Christmas in 1989, smriti of ABC langu ...

  5. jsp 重定向技术

    页面重定向之后,request对象的属性全部失效,生成一个新的requeset对象

  6. RedHat Enterprise Linu…

    RedHat Enterprise Linux 6.4 使用Centos 6 的yum 源问题 2015.04.09 一.问题描述 有时在使用RedHat 系统进行安装某些软件时,会出现如下提示: T ...

  7. salesforce零基础学习(七十七)队列的实现以及应用

    队列和栈简单的区别为栈是后进先出,队列是先进先出.队列也是特殊的线性表,所以队列也分为顺序存储结构和链式存储结构.本篇主要描述顺序存储结构. 我们先假定一个队列里有5个元素,当我们添加新元素时,添加到 ...

  8. 应届毕业生如何通过学习Linux系统选择一份高薪职业

    2017年全国高校毕业生人数795万,史上"更难就业季"大学生就业形势,再加上出国留学回来的约30万以及没有找到工作的往届毕业生,预计将有1000多万大学生同时竞争. 如果我们不是 ...

  9. 数据库db2错误代码大全

    sqlcode sqlstate 说明000 00000 SQL语句成功完成01xxx SQL语句成功完成,但是有警告+012 01545 未限定的列名被解释为一个有相互关系的引用+098 01568 ...

  10. semantic UI first web

    官方文档:https://semantic-ui.com/introduction/getting-started.html semantic  UI: SemanticUI是一款语义化设计的前端开源 ...