`
234390216
  • 浏览: 10232329 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:462597
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1775472
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1398311
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:394999
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:679961
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:530847
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1183873
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:467815
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:151372
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:68129
社区版块
存档分类
最新评论

Spring(19)——Profile(一)

阅读更多

19 Profile

有的时候我们可能需要在不同的环境下使用不同的bean定义,如在开发环境直接使用直接定义的数据源,而在生产环境使用对应的JNDI数据源等。针对这种需求,Spring给我们引入了一个profile的概念,其允许我们将在特定环境下需要使用的bean定义为不同的profile,然后只有在对应的profile激活的情况下才使用对应的bean定义。打个比方我们有一个beanA需要在开发环境才启用,则可以定义其对应的profile为dev,然后另外有一个beanB需要在生产环境才启用,则可以定义其对应的profile为production。那么只有当我们指定对应的profile为dev时beanA才会被激活,只有profile为production时beanB才会被启用,其它情况下都是未启用的。

19.1 指定profile

针对不同的bean定义方式,对应的profile的指定方式也是不一样的。

19.1.1 基于XML配置定义的bean

对于这种形式的bean定义,对应的profile指定是通过在<beans/>标签上的profile属性进行指定的。如下示例我们就通过在<beans/>标签上指定了profile为dev,那么对应<beans/>中定义的所有的bean都只有在profile为dev时才可用,这也包括其中通过<context:component-scan/>定义扫描到的其它bean定义。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd"
    profile="dev">

	<bean id="hello" class="com.elim.learn.spring.bean.Hello"/>

</beans>

profile也可以定义在内置的标签上,如下我们指定了当前文件的profile为dev,但是在其内部定义了一个内置的<beans/>标签,并指定其对应的profile为production,这样只有在dev和production两种profile都激活时,Spring才会扫描对应的类路径进行bean定义,因为我们在最顶层的<beans/>上指定了profile为dev,在<context:component-scan/>上级<beans/>上指定了profile为production,对于这种嵌套指定profile的形式是需要同时激活多个profile里面的定义才会生效的。

<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd"
    profile="dev">
	<!-- 只有profile为production时才进行扫描 -->
	<beans profile="production">
		<context:component-scan base-package="com.app">
			<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
		</context:component-scan>
	</beans>
	<!-- 只有profile为dev时才可用 -->
	<beans>
		<bean id="hello" class="com.elim.learn.spring.bean.Hello"/>
	</beans>

</beans>

在上述示例中如果我们希望<context:component-scan/>能够在production激活的情况就生效,而不用管dev,则可以取消最顶层的profile=”dev”。
此外,profile除了可以直接指定一个值以外,还可以同时指定多个profile,中间以逗号隔开,表示只要其中一个profile是激活状态即可启用当前的定义。如果profile是以感叹号“!”开始的,则表示需要对应的profile没有激活的情况下才可用。

	<!-- 当p1或p2对应的profile为激活状态时,当前定义才是可用的 -->
	<beans profile="p1,p2">
		<!-- .... -->
	</beans>
	
	<!-- 当没有激活p1对应的profile时,当前定义才是可用的 -->
	<beans profile="!p1">
		<!-- .... -->
	</beans>

19.1.2 自动扫描的bean定义

对于自动扫描的bean定义,如果我们是需要将所有的扫描类统一使用一种profile,则对于基于XML配置的bean容器定义我们可以使用<beans/>标签包裹<context:component-scan/>,并在<beans/>标签上通过profile属性指定对应的profile。而对于基于Java类配置的自动扫描,如果需要将所有的扫描类统一使用一种profile,则可以在对应的配置类上使用@Profile进行标注,并通过其value属性指定对应的profile。
如果我们只是希望将自动扫描的某些类指定为特定的profile,则可以在对应的类上使用@Profile进行标注,并通过对应的value属性指定对应的profile。如下示例就指定了当前bean对应的profile为dev。

@Component
@Profile("dev")
public class Hello {
	
}

使用@Profile时也可以同时指定多个profile,这个时候多个profile之间的关系就是或,即只要其中的某个profile处于激活状态当前定义即为可用。如下示例即表示当p1或p2对应的profile处于激活状态时,如下定义才是可用的。

@Component
@Profile({"p1", "p2"})
public class Hello {

}

使用@Profile时也可以使用“!”前缀,表示只有在对应的profile不处于激活状态时当前定义才是可用的。如下示例即表示只有在p1对应的profile不处于激活状态时对应的定义才是可用的。

@Component
@Profile({"!p1"})
public class Hello {

}

此外,我们还可以自定义一个注解,然后使用@Profile进行标注,并指定对应的profile,这样我们就可以使用该自定义注解来替代特定的@Profile来使用。如在我们的应用中有许多bean需要使用@Profile(“production”)进行标注,那么我们就可以自定义如下这样一个@Production注解来代替@Profile(“production”)。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Profile("production")
public @interface Production {

}

如果原来我们有一个bean定义成如下这样。

@Component
@Profile("production")
public class Hello {
	
}

因为我们的自定义的@Production注解上使用了@Profile进行标注,并且指定了profile为production,那么可以用@Production来替代@Profile(“production”),所以上述定义也可以定义成如下这样。

@Component
@Production
public class Hello {
	
}

19.1.3 基于Java类配置定义的bean

对于基于Java类的配置我们可以在对应的配置类上使用@Profile来指定整个配置类对应的bean定义都必须在特定的profile下才可用,如下示例,我们指定了配置类SpringConfig只有在profile为dev的情况下才是可用的,这包括直接在SpringConfig中定义的bean,也包括通过@Import引入的其它配置类中定义的bean,还包括通过@ImportResource引入的XML文件中定义的bean,都只能在profile为dev时才可用。

@Configuration
@Profile("dev")
public class SpringConfig {

	@Bean
	public Hello hello() {
		return new Hello();
	}
	
	@Bean
	public World world() {
		return new World();
	}
	
}

当我们只需要指定某个bean对应的profile时,我们可以在对应的bean定义上使用@Profile进行定义。当Java配置类和实际的bean定义方法上都使用@Profile指定了profile时表示两者都需要满足才行。如下示例,表示hello是在profile为dev的情况下可用,它自己没有指定,而是从Java配置类SpringConfig继承来的。而world将需要dev和production两种profile都激活的情况下才是可用的。

@Configuration
@Profile("dev")
public class SpringConfig {

	@Bean
	public Hello hello() {
		return new Hello();
	}
	
	@Bean
	@Profile("production")
	public World world() {
		return new World();
	}
	
}

当Java配置类上没有指定@Profile,而直接在bean定义上指定了@Profile时则表示当前的bean需要在指定的profile激活的情况下才可用。如下示例中hello将在任何profile下都是可用的,而world将只有在激活了production这种profile的情况下才是可用的。

 

@Configuration
public class SpringConfig {

	@Bean
	public Hello hello() {
		return new Hello();
	}
	
	@Bean
	@Profile("production")
	public World world() {
		return new World();
	}
	
}

 

0
0
分享到:
评论

相关推荐

    Spring Mvc——第一个应用程序

    **Spring MVC —— 第一个应用程序** Spring MVC 是 Spring 框架的一个模块,主要用于构建 Web 应用程序。它提供了一种模型-视图-控制器(MVC)架构,简化了开发过程,使得开发者可以专注于业务逻辑而不必过于关心...

    Spring————面试题库

    Spring是一个开源的Java平台,它是Java应用程序开发的一个综合和广泛的基础支持平台。Spring框架的目的是帮助Java开发者解决在开发应用程序时遇到的基础性问题,让开发者能够专注于业务逻辑的开发,而不必担心底层...

    Spring系列——MVC框架整合.md

    Spring系列——MVC框架整合.md

    征服Spring AOP—— Schema

    本文将深入探讨“Spring AOP——Schema”,这是Spring AOP的一种配置方式,通过XML schema定义切面和通知。 首先,我们需要理解AOP的基本概念。面向切面编程是一种编程范式,旨在提高软件的模块化程度,将关注点...

    Quartz Spring整合——附带webservice Demo

    在"Quartz Spring整合——附带webservice Demo"的项目中,我们可以看到如何将这两个强大的工具结合在一起。这个Demo可能包含了一个使用Quartz调度器来触发Web服务调用的示例。Web服务(Webservice)是一种基于标准的...

    Spring特性——事件驱动模型

    本篇文章将深入探讨Spring框架的一个重要特性——事件驱动模型。通过理解这一特性,开发者可以更好地利用Spring来实现应用间的通信和协调,提高系统的灵活性和可扩展性。 事件驱动模型是一种设计模式,它基于发布/...

    Spring框架的简单实现

    【SSH进阶之路】一步步重构容器实现Spring框架——从一个简单的容器开始(八) 【SSH进阶之路】一步步重构容器实现Spring框架——解决容器对组件的“侵入式”管理的两种方案--服务定位器和IoC容器(九) 【SSH进阶之路】...

    SpringCloud——声明性REST客户端(Feign)

    【SpringCloud——声明性REST客户端(Feign)】 在分布式微服务架构中,服务之间的通信是至关重要的。Spring Cloud提供了一种优雅的方式,通过Feign客户端来实现这一目标。Feign是一个声明式的Web服务客户端,它...

    SpringCloud——Zookeeper(注册中心)

    SpringCloud为Zookeeper提供了一个名为`spring-cloud-starter-zookeeper`的启动器,允许开发者轻松地将Zookeeper集成到SpringBoot应用中。首先,我们需要在项目中引入依赖: ```xml &lt;groupId&gt;org.springframework...

    SpringCloud——服务注册(consul)

    Spring Cloud作为微服务解决方案的一部分,提供了多种服务发现工具,其中Consul是其中一个流行的选择。本文将深入探讨Spring Cloud如何整合Consul实现服务注册。 Consul是由HashiCorp公司开发的一款分布式系统服务...

    SpringCloud——分布式跟踪(Sleuth)

    Spring Cloud Sleuth是Spring Cloud生态系统的一部分,它实现了分布式追踪的标准——OpenTracing和Zipkin。通过集成Sleuth,开发者可以在不修改代码的情况下,轻松地在微服务架构中实现请求的全链路追踪。 二、核心...

    SpringCloud——客户端负载平衡器(Ribbon)

    Ribbon是一个客户端负载均衡器,它可以很好地控制HTTP和TCP客户端的行为。

    Spring开发指南——中文版

    《Spring开发指南——中文版》是由夏昕编著的一本针对Spring框架的中文教程,旨在帮助开发者更好地理解和应用Spring框架。Spring是Java平台上的一个核心框架,广泛应用于企业级应用开发,提供了一种全面的编程和配置...

    Java EE 框架整合开发⼊⻔到实战——Spring+Spring MVC+MyBatis(微课版)课后习题答案.pdf

    这份文档名为《Java EE 框架整合开发入门到实战——Spring+Spring MVC+MyBatis(微课版)课后习题答案.pdf》,它显然是关于Java EE中流行的三个框架整合使用的教程。这三个框架分别是Spring、Spring MVC和MyBatis,...

    spring——第十四节素材.rar

    标题中的“spring——第十四节素材.rar”表明这是一个关于Spring框架的教程材料,可能是课程的第14节内容。Spring是Java开发中最广泛使用的轻量级框架,它提供了丰富的功能来简化企业级应用的开发,包括依赖注入、...

Global site tag (gtag.js) - Google Analytics