主要内容:

  ●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,否则就会被忽略。

未完待续...

Spring学习笔记-高级装配-03的更多相关文章

  1. Spring学习(三)--高级装配

    一.Spring profile 在开发软件的时候,有一个很大的挑战就是将应用程序从一个环境迁 移到另外一个环境.开发阶段中,某些环境相关做法可能并不适合迁 移到生产环境中,甚至即便迁移过去也无法正常 ...

  2. spring学习总结——高级装配学习四(运行时:值注入、spring表达式)

    前言: 当讨论依赖注入的时候,我们通常所讨论的是将一个bean引用注入到另一个bean的属性或构造器参数中.bean装配的另外一个方面指的是将一个值注入到bean的属性或者构造器参数中.在没有学习使用 ...

  3. spring学习总结——高级装配学习一(profile与@Conditional)

    前言: 在上一章装配Bean中,我们看到了一些最为核心的bean装配技术.你可能会发现上一章学到的知识有很大的用处.但是,bean装配所涉及的领域并不仅仅局限于上一章 所学习到的内容.Spring提供 ...

  4. spring学习总结——高级装配学习三(Bean的作用域)

    一.bean的作用域 在默认情况下,Spring应用上下文中所有bean都是作为以单例(singleton)的形式创建的.也就是说,不管给定的一个bean被注入到其他bean多少次,每次所注入的都是同 ...

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

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

  6. [Spring学习笔记 2 ]装配各种类型的属性 map,list,array,null,properties

    一.spring Ioc容器补充(1) Spring Ioc容器 DI(依赖注入): 注入的方式:设值方法注入setter(属性注入)/构造子注入(构造函数传入依赖的对象)/字段注入field(注解) ...

  7. Spring学习笔记--自动装配Bean属性

    Spring提供了四种类型的自动装配策略: byName – 把与Bean的属性具有相同名字(或者ID)的其他Bean自动装配到Bean的对应属性中. byType – 把与Bean的属性具有相同类型 ...

  8. spring学习笔记(一) Spring概述

    博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书.  强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring ...

  9. 不错的Spring学习笔记(转)

    Spring学习笔记(1)----简单的实例 ---------------------------------   首先需要准备Spring包,可从官方网站上下载.   下载解压后,必须的两个包是s ...

随机推荐

  1. 2019ccpc哈尔滨打铜记

    小学生日记: 2019.10.13,哈尔滨,打了个铜 开头 先说结论,这次失败,我的锅70%,sdl的锅5%,ykh25% Day0 周五, 我们队出现了奇怪的厄运上身 首先是我中途在飞机上数据线突然 ...

  2. Kafka系列2:深入理解Kafka消费者

    Kafka系列2:深入理解Kafka消费者 上篇聊了Kafka概况,包含了Kafka的基本概念.设计原理,以及设计核心.本篇单独聊聊Kafka的消费者,包括如下内容: 生产者是如何生产消息 如何创建生 ...

  3. windows10 CTCP

    windows上除了普通tcp之外,有一个CTCP. 据说可以提升长延时情况下的吞吐量. win7可以方便的通过netsh int tcp set global congestionprovider= ...

  4. Windows+Python+Selenium基础篇之1-环境搭建

    1.所需工具包1.1Selenium for python1.2  Python  1.3  Notepad++或python IDE 2.  环境搭建2.1  下载和安装Pythonpython2. ...

  5. JVM性能优化系列-(5) 早期编译优化

    5. 早期编译优化 早起编译优化主要指编译期进行的优化. java的编译期可能指的以下三种: 前端编译器:将.java文件变成.class文件,例如Sun的Javac.Eclipse JDT中的增量式 ...

  6. VMware vCenter Server6.5安装及群集配置介绍

    借助 VMware vCenterServer,可从单个控制台统一管理数据中心的所有主机和虚拟机,该控制台聚合了集群.主机和虚拟机的性能监控功能. VMware vCenterServer 使管理员能 ...

  7. javascript30--day01--Drum kit

    相关视频链接:https://www.bilibili.com/video/av8481988/?p=3 Drum kit 做题思路(1)监听键盘事件 addEventListener(‘事件名’,执 ...

  8. [javascript] test() 方法进行正则验证

    test() 方法用于检测一个字符串是否匹配某个模式 最近遇到的某业务中进行发票抬头的正则验证如下: console.log(/^[a-zA-Z\u4e00-\u9fa5\s()()<>& ...

  9. Cesium案例解析(三)——Camera相机

    目录 1. 概述 2. 实例 2.1. Camera.html 2.2. Camera.js 2.2.1. 飞行至某一点 2.2.2. 飞行至某区域 2.2.3. 两地之间飞行 2.2.4. 设置视图 ...

  10. Mysql 字符串转数字类型

    使用场景: 在数据库中进行数字比较,但是数字的存储格式是varchar的时候可以使用以下方法进行转换,然后进行比较 方法一:SELECT CAST('123' AS SIGNED); 方法二:SELE ...