You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 22:05:01