Using Spring 4 Condition To Control Bean Registration

Spring 4 introduces the Condition interface which supports a condition to checked and registers a bean only when the condition is matched. In this blog, I will demonstrate how to implement a custom condition interface which will register beans when the active profiles match a regex defined in the condition. This would be useful, for example, to inject mock beans when testing while using the actual implementations at deployment. The classes implemented here is a slight modification of the standard @Profile annotation and supporting classes.


First we define the interface @ProfileRegex as follows

@Target({ElementType.TYPE, ElementType.METHOD})
public @interface ProfileRegex {
      * The profile regex for which the annotated component should be registered.
      String value();

The interface requires a String value attribute which define the regex to use to match the spring context’s active profiles. Note the use of @Condition annotation to define the class that implements the Condition interface, i.e. ProfileRegexCondition.


The class ProfileRegexCondition implements the Condition interface

class ProfileRegexCondition implements Condition {

 public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
       Environment environment = context.getEnvironment();
       if (environment != null) {
            String[] profiles = environment.getActiveProfiles();
            MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(ProfileRegex.class.getName());
           if (attrs != null) {
                for (Object value : attrs.get("value")) {
                     for (String profile : profiles) {
                          boolean matches = Pattern.matches((String) value, profile);
                          if (matches) {
                             return true;
                return false;
      return true;

The Condition interface has only one method matches() which determines whether the condition is matched. In our implementation, it iterates all the active profiles and return true if the profile matches the regex as defined in the value of the @ProfileRegex annotation.


Suppose we want to register a mock bean for unit testing. We could define the following bean configuration class

public class TestConfiguration {
     MyService myServiceMockBean() {
         return mock(MyService.class);

Note the use of @ProfileRegex annotation to only register the beans when the active profile matches the regex “test”.  Also, the @ProfileRegex annotation can also be applied to the individual @Bean method to provide a more fine control over bean registration. The following configuration class does the opposite of the above and registers whenever the active profiles does not match the regex “test”.

public class ServiceConfiguration {

    MyService myServiceBean() {
         return new MyServiceImpl();

Below is the unit test to verify the correct (mock) bean is registered

@SpringApplicationConfiguration(classes = TestConfiguration.class)
public class ServiceConfigTest {
    private ApplicationContext context;

    public void testProfileRegexCondition() {
         MyService service = context.getBean(MyService.class);
         assertThat(service, CoreMatchers.notNullValue());
         assertThat(new MockUtil().isMock(service), equalTo(true));

Finally, Spring Boot provides a number of useful conditional annotations under the package org.springframework.boot.autoconfigure.condition. See the javadoc for more details.

About Raymond Lee
Professional Java/EE Developer, software development technology enthusiast.

Comments are closed.