@Condition is new Spring4 comment, the role in meeting the conditions for injection into Spring bean container, in Spring Boot a large number of uses @Condition notes, for example @ConditionOnBean as the core Spring Boot automated configuration. Source:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Conditional { /** * All {@link Condition}s that must {@linkplain Condition#matches match} * in order for the component to be registered. */ Class<? extends Condition>[] value(); }
Annotation value is to achieve a Condition interface, Condition Interface Source:
public interface Condition { /** * Determine if the condition matches. * @param context the condition context * @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class} * or {@link org.springframework.core.type.MethodMetadata method} being checked. * @return {@code true} if the condition matches and the component can be registered * or {@code false} to veto registration. */ boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata); }
We did a simple example, depending on the profile settings, registered in the Spring bean in the container is different, first define a Service interface:
public interface ProfileService { void show(); }
Then define two classes implement:
public class ProfileDevService implements ProfileService { @Override public void show() { System.out.println("this is dev"); } }
public class ProfilePrdService implements ProfileService { @Override public void show() { System.out.println("this is prd"); } }
Both classes can only register a window in the Spring, the method is to determine the profile, two judging categories:
public class OnDevProfile implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return context.getEnvironment().getActiveProfiles()[0].equals("dev"); } }
public class OnPrdProfile implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return context.getEnvironment().getActiveProfiles()[0].equals("prd"); } }
Both classes implement the Condition interface in the comment @Condition need to use these two classes:
@Configuration public class ConditionConfiguration { @Bean @Conditional(OnDevProfile.class) public ProfileService devProfileService() { return new ProfileDevService(); } @Bean @Conditional(OnPrdProfile.class) public ProfileService prdProfileService() { return new ProfilePrdService(); } }
He added @Condition comment at the time of injection bean, so whether the registration is successful, matchs method value depends on the class notes @Condition return value.
Start a container:
public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.getEnvironment().setActiveProfiles("prd"); context.register(ConditionConfiguration.class); context.refresh(); ProfileService profileService = context.getBean(ProfileService.class); profileService.show(); context.close(); }
Setting active profiles here as "prd", therefore the console print is this is prd, the active profiles changed to "dev" print is this is dev