Testing the below Spring 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <bean id="bean1" class="com.Test2"> </bean> <beans profile="DEV"> <bean id="bean1" class="com.Test1"> </bean> </beans> <bean id="bean1" class="com.Test2"> </bean> </beans>
It seems that com.Test2
is loaded if a Spring profile is not set. Is this the expected behavior ?
I’m just trying to understand how Spring loads classes if profiles are set/unset. It seems that if a profile is not set then Spring will create the class if it exists outside the profile, if a profile is set then Spring will create the class for the profile. If the class also exists outside the profile it is not loaded when the profile is loaded.
So, in the above example if DEV profile is set then com.test1
is loaded for bean id bean1
, if no profile is set then com.test2
is loaded for bean1
. Is this the expected behavior.
Advertisement
Answer
The behavior you described is the expected one.
Usually, in Spring there is a rule of thumb related with bean loading: every bean that is loaded with the same name as another one, and that is processed later, will override the older one.
The key term here is being processed later.
In your specific use case, first, every bean that is not defined in any profile will be included, at first glance, in the Spring context.
When you activate a profile, as in your example, you are making visible a new piece of configuration: if this configuration contains a bean with the same name as other one already processed, as indicated, it will override this bean in the Spring context.
This fact is always true independently of the mechanism, Java, XML configuration, or both, you use to define the beans.
It is important to note that the order in which Spring process the different configurations that can be found across the code and different libraries is not deterministic. In your specific use case, when using XML configurations, you can safely assume that it will load the different configurations in the order in which they are imported in your main configuration files (the ones configured for the context load mechanism you choose) and, for every one of them, in the order in which the beans are defined within the same XML file, if that is the case.
This general override rule is always true except in the case you use Spring Boot 2: in this case, if you override a bean by name, by default, an exception will be raised indicating that a bean with this name is already defined in the Spring context. You can restore the usual override behavior by specifying the following configuration property:
spring.main.allow-bean-definition-overriding=true
In addition to profiles, Spring Boot will allow you to load a bean or not depending on several types of conditions. This mechanism is applied usually when loading @Configuration
s in the auto configuration process.