Spring中如何处理可用条件来自数据库的可选Bean?
解决方案
方法1:通过Spring工具类识别NullBean代理
Spring会对返回null的Bean包装成NullBean代理,可借助AopUtils或ClassUtils获取真实对象并判断:
import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.support.NullBean; // 在flow方法中调整判断逻辑 RotatingServerAdvice advice = adviceProvider.getIfAvailable(); if (advice != null) { Object target = AopUtils.getTargetObject(advice); if (target instanceof NullBean) { advice = null; } } return advice == null ? null : IntegrationFlows...;
也可以直接通过toString结果判断(你提到代理toString返回"null"):
if (advice != null && "null".equals(advice.toString())) { advice = null; }
方法2:自定义Condition控制Advice Bean的创建
自定义Condition类,在其中查询数据库判断是否有可用SFTP配置,以此决定是否创建RotatingServerAdvice Bean:
import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; public class HasSftpConfigCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { InterfaceRepo interfaceRepo = context.getBeanFactory().getBean(InterfaceRepo.class); return interfaceRepo.findAll().stream().anyMatch(Interface::isReceivingData); } }
给advice方法添加条件注解:
@Bean @RefreshScope @Conditional(HasSftpConfigCondition.class) RotatingServerAdvice advice(DelegatingSessionFactory<LsEntry> delegatingSessionFactory) { // 无需再判断列表为空,Condition已确保有数据 List<RotationPolicy.KeyDirectory> keyDirectories = interfaceRepo.findAll().stream() .filter(Interface::isReceivingData) .map(x -> new RotationPolicy.KeyDirectory( new SessionFactoryKey(x.getHostname(), x.getPort(), x.getUsername()), x.getDirectory())) .toList(); return new RotatingServerAdvice(delegatingSessionFactory, keyDirectories); }
此时数据库为空时,RotatingServerAdvice Bean不会被创建,adviceProvider.getIfAvailable()会返回真实null,flow方法的判断逻辑可正常工作。
方法3:返回空实现替代null
创建一个空的Advice实现,当无配置时返回该实例,再在flow方法中判断类型:
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; // 自定义空Advice,绕过RotatingServerAdvice的非空断言 public class EmptyRotatingAdvice implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { // 空实现,直接执行原方法 return invocation.proceed(); } }
修改advice方法:
@Bean @RefreshScope Object advice(DelegatingSessionFactory<LsEntry> delegatingSessionFactory) { List<RotationPolicy.KeyDirectory> keyDirectories = ...; return keyDirectories.isEmpty() ? new EmptyRotatingAdvice() : new RotatingServerAdvice(delegatingSessionFactory, keyDirectories); }
在flow方法中调整判断:
Object advice = adviceProvider.getIfAvailable(); if (advice instanceof EmptyRotatingAdvice) { return null; } // 否则强转为RotatingServerAdvice并创建IntegrationFlow return IntegrationFlows...;
内容的提问来源于stack exchange,提问作者Guerric P
相关产品推荐
相关产品推荐

