Skip to content

Instantly share code, notes, and snippets.

@alexengrig
Last active August 24, 2022 13:07
Show Gist options
  • Save alexengrig/0c434ff48eaedd77a59a965c462ce35b to your computer and use it in GitHub Desktop.
Save alexengrig/0c434ff48eaedd77a59a965c462ce35b to your computer and use it in GitHub Desktop.
Spring Bean Condition - at least one bean
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.lang.NonNull;
import java.util.Map;
public class AtLeastOneBeanCondition implements Condition {
@Override
public boolean matches(ConditionContext context, @NonNull AnnotatedTypeMetadata metadata) {
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
if (beanFactory == null) {
return false;
}
MergedAnnotations annotations = metadata.getAnnotations();
if (!annotations.isPresent(ConditionalAtLeastOneBean.class)) {
return false;
}
MergedAnnotation<ConditionalAtLeastOneBean> annotation = annotations.get(ConditionalAtLeastOneBean.class);
Class<?>[] types = annotation.getClassArray("value");
for (Class<?> type : types) {
try {
Map<String, ?> beanByName = beanFactory.getBeansOfType(type, true, false);
if (!beanByName.isEmpty()) {
return true;
}
} catch (RuntimeException ignore) {
// ignore exception
}
}
return false;
}
}
import org.springframework.context.annotation.Conditional;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The context has at least one bean.
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Conditional(AtLeastOneBeanCondition.class)
public @interface ConditionalAtLeastOneBean {
/**
* The class types of beans that should be checked.
*/
Class<?>[] value();
}
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfiguration {
@Bean
@ConditionalOnLeastOneBean({MyService1.class, MyService2.class})
public IntegrationJournalConfigKeeper<T> myService3(MyService1 service1, MyService2 service2) {
return new MyService3(service1, service2);
}
@Bean
@ConditionalOnMissingBean(MyService1.class)
public MyService1 myService1() {
return new StubService1();
}
@Bean
@ConditionalOnMissingBean(MyService2.class)
public MyService2 myService2() {
return new StubService2();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment