Spring(19)——Profile(一)

19 Profile

Sometimes we may need to use different bean definitions in different environments, such as directly using the directly defined data source in the development environment, and using the corresponding JNDI data source in the production environment. In response to this requirement, Spring introduces a concept of profile to us, which allows us to define beans that need to be used in a specific environment as different profiles, and then use the corresponding bean definition only when the corresponding profile is activated. For example, if we have a beanA that needs to be enabled in the development environment, we can define its corresponding profile as dev, and then if there is another beanB that needs to be enabled in the production environment, we can define its corresponding profile as production. Then beanA will be activated only when we specify the corresponding profile as dev, beanB will be enabled only when the profile is production, and not enabled in other cases.

19.1 Specified profile

For different bean definitions, the corresponding profiles are specified in different ways.

19.1.1 Beans defined based on XML configuration

For this form of bean definition, the corresponding profile specification is specified through <beans/>the profile attribute on the tag. In the following example, we <beans/>specify the profile as dev on the label, then <beans/>all the beans defined in the corresponding are available only when the profile is dev, which also includes <context:component-scan/>other bean definitions scanned by definition.

<?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>

The profile can also be defined on the built-in label. As follows, we specify the profile of the current file as dev, but define a built-in <beans/>label inside it, and specify its corresponding profile as production, so that there are only two profiles in dev and production. When both are activated, Spring will scan the corresponding classpath for bean definition, because we <beans/>specify the profile as dev on the topmost level, and specify the profile as production on the <context:component-scan/>upper level . <beans/>The definitions in multiple profiles are activated to take effect.

<?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 " >
	 <!-- Only scan if profile is 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 >
	 <!-- Only available if profile is dev --> 
	< beans >
		<bean id="hello" class="com.elim.learn.spring.bean.Hello"/>
	</beans>

</beans>

In the above example, if we want <context:component-scan/>to be able to take effect when production is activated, regardless of dev, we can cancel the topmost profile="dev".
In addition, in addition to directly specifying a value, profiles can also specify multiple profiles at the same time, separated by commas, indicating that as long as one of the profiles is active, the current definition can be enabled. If the profile starts with an exclamation mark "!", it means that the corresponding profile can only be used when it is not activated.

	<!-- The current definition is only available when the profile corresponding to p1 or p2 is active --> 
	< beans  profile = " p1,p2 " >
		 <!-- .... --> 
	</ beans >
	
	<!-- The current definition is only available when the profile corresponding to p1 is not activated --> 
	< beans  profile = " !p1 " >
		 <!-- .... --> 
	</ beans >

19.1.2 Autoscanned bean definitions

For automatically scanned bean definitions, if we need to use one profile for all scanning classes, we can <beans/>wrap the bean container definitions based on XML configuration with tags <context:component-scan/>, and <beans/>specify the corresponding profile through the profile attribute on the tag. For automatic scanning based on Java class configuration, if you need to use one profile for all scanning classes, you can use @Profile to mark the corresponding configuration class, and specify the corresponding profile through its value attribute.
If we just want to designate some of the automatically scanned classes as a specific profile, we can use @Profile to mark the corresponding class, and specify the corresponding profile through the corresponding value attribute. The following example specifies that the profile corresponding to the current bean is dev.

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

When using @Profile, you can also specify multiple profiles at the same time. At this time, the relationship between multiple profiles is OR, that is, as long as one of the profiles is active, the current definition is available. The following example means that the following definitions are only available when the profile corresponding to p1 or p2 is active.

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

}

The "!" prefix can also be used when using @Profile, indicating that the current definition is only available if the corresponding profile is not active. The following example means that the corresponding definition is only available when the profile corresponding to p1 is not active.

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

}

In addition, we can also customize an annotation, and then use @Profile to annotate and specify the corresponding profile, so that we can use this custom annotation to replace a specific @Profile. If there are many beans in our application that need to be annotated with @Profile("production"), then we can customize the following @Production annotation instead of @Profile("production").

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

}

If we had a bean defined as follows.

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

Because our custom @Production annotation is marked with @Profile, and the profile is specified as production, then @Production can be used instead of @Profile("production"), so the above definition can also be defined as follows.

@Component
@Production
public class Hello {
	
}

19.1.3 Beans defined based on Java class configuration

For Java class-based configuration, we can use @Profile on the corresponding configuration class to specify that the bean definitions corresponding to the entire configuration class must be available under a specific profile. In the following example, we specify that the configuration class SpringConfig is only available when the profile is dev This includes beans defined directly in SpringConfig, beans defined in other configuration classes introduced through @Import, and beans defined in XML files introduced through @ImportResource, all of which can only be Only available when profile is dev.

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

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

When we only need to specify the profile corresponding to a bean, we can use @Profile to define the corresponding bean definition. When the profile is specified using @Profile on both the Java configuration class and the actual bean definition method, it means that both need to be satisfied. The following example shows that hello is available when the profile is dev, it is not specified by itself, but is inherited from the Java configuration class SpringConfig. The world will only be available if both the dev and production profiles are activated.

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

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

When @Profile is not specified on the Java configuration class, and @Profile is specified directly on the bean definition, it means that the current bean needs to be available only when the specified profile is activated. In the following example hello will be available under any profile, while world will only be available if the production profile is activated.

 

@Configuration
public class SpringConfig {

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

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326334876&siteId=291194637