Spring学习笔记-高级装配-03

时间:2022-09-07 17:38:13

主要内容:

  ●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学习&lpar;三&rpar;--高级装配

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

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

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

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

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

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

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

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

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

  6. &lbrack;Spring学习笔记 2 &rsqb;装配各种类型的属性 map&comma;list&comma;array&comma;null&comma;properties

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

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

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

  8. spring学习笔记&lpar;一&rpar; Spring概述

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

  9. 不错的Spring学习笔记&lpar;转&rpar;

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

随机推荐

  1. linux系统内存爆满的解决办法!~

    1.首先用free工具检查一下内存的使用情况: 这个是我的linux时时数据 Mem: 4046824 763620 3283204 9004 10284 61560  -/+buffers/cach ...

  2. &lbrack;设计模式&rsqb; Javascript 之 外观模式

    外观模式说明 说明:外观模式是用于由于子系统或程序组成较复杂而提供的一个高层界面接口,使用客户端更容易访问底层的程序或系统接口; 外观模式是我们经常使用遇到的模式,我们经常涉及到的功能,可能需要涉及到 ...

  3. bzoj2119

    题意就是差分后求形如ABA的串的个数,B的长度为M 这是2011国家集训队互测的试题,是道好题,我直接给出出题人的题解吧: 对于这种在线性序列上的组合计数问题,我们很容易想到一个工具:分治!分治算法在 ...

  4. 解决NTFS分区上的代码在linux上编译后没有权限执行

    win7下的cpp代码,在ubuntu下编译后,可执行文件不能执行,root也不行. 将代码拷贝到ubuntu上,再编译生成的可执行文件则可以执行.或者将win7分区上的可执行文件拷贝出来,然后chm ...

  5. java Object类

    常用的共性内容 1,实现任何对象的比较,一般比较同一种对象的比较 Object1.equals(Object obj);等同于Object1 == obj: 只有当两个引用指向同一个对象时方法返回tr ...

  6. doubango简介

    1.doubango官网:http://www.doubango.org/ doubango常用项目国内镜像(放在淘宝的svn服务器),目前有4个项目:doubango, idoubs, imsdro ...

  7. CSS3微信启动页天王星版

    今天被微信启动页刷屏了. 一直还以为启动页背景显示的月球的.今天才了解到这么有含义. 我也蹭一下微信的热度,做一个HTML+CSS版本的. 用CSS画地球太困难了,来个简单点的,天王星版. 主要使用到 ...

  8. 在阿里云上搭建 Spark 实验平台

    在阿里云上搭建 Spark 实验平台 Hadoop2.7.3+Spark2.1.0 完全分布式环境 搭建全过程 [传统文化热爱者] 阿里云服务器搭建spark特别坑的地方 阿里云实现Hadoop+Sp ...

  9. 注册表命令 regedit32

    转自 https://zhidao.baidu.com/question/1958216489744783460.html Regedt32.exe 不支持注册表项文件 (.reg) 的导入和导出. ...

  10. Python 描述符 data 和 non-data 两种类型

    仅包含__get__的,是non-data descriptor, 如果实例__dict__包含同名变量, 则实例优先; 如果还包含__set__, 则是data descriptor, 优先于实例_ ...