繁体   English   中英

Spring,注入仅包含特定 bean 的 bean 列表

[英]Spring, injecting a list of beans with only specific beans included

在 Spring 中,当我注入一个 beans 列表时,我只想注入接口的特定实现,当从不同的地方使用时。 这可能吗? 配置这个的最干净的方法是什么? 例如,我有以下验证器:

public interface Validator {
    Optional<Error> validate(MultipartFile file);
}

public class Validator1 implements Validator {
    public Optional<Error> validate(MultipartFile file) {
        // do stuff
    }
}

public class Validator2 implements Validator {
    public Optional<Error> validate(MultipartFile file) {
        // do stuff
    }
}

public class Validator3 implements Validator {
    public Optional<Error> validate(MultipartFile file) {
        // do stuff
    }
}

然后我有一个类似于此的验证服务:

public class ValidationService {
    @Autowired
    private List<Validator> validators;

    public List<Error> validate(MultipartFile file) {
        List<Error> errors = new ArrayList<>();
        validators.forEach(v -> {
            Optional<Error> error = v.validate(file);
            if (error.isPresent()) {
                errors.add(error.get());
            }
        });
        return errors;
    }
}

然后我有一些使用 ValidationService 的服务,例如:

public class Service1 {

    @Autowired
    private ValidationService validationService;

    public void doStuff(MultipartFile file) {
        ...
        validationService.validate(file);
        ...
    }
}

public class Service2 {

    @Autowired
    private ValidationService validationService;

    public void doStuff(MultipartFile file) {
        ...
        validationService.validate(file);
        ...
    }
}

当Service1 调用validate 时,我只想将Validator1 和Validator2 注入到ValidatorService 中。 当Service2调用validate时,我只希望Validator2和Validator3已经注入到ValidatorService中。

希望我已经解释清楚了。 在此先感谢您提供的任何帮助。

使用 @Qualifier 注释像这样创建 bean --

@Qualifier("validator1")
public class Validator1 implements Validator {
   public Optional<Error> validate(MultipartFile file) {
            // do stuff
        }
}

@Qualifier("validator2")
public class Validator2 implements Validator {
    public Optional<Error> validate(MultipartFile file) {
        // do stuff
    }
}
@Qualifier("validator3")
public class Validator3 implements Validator {
    public Optional<Error> validate(MultipartFile file) {
        // do stuff
    }
}

并像这样注入它---

@Autowired("validator1")
private ValidationService validationService;

更新

您还可以像这样为所有验证器创建一个 bean 集合 -

@Bean("validators")
public List<Validator> validatorList(Validator1 validator1, Validator2 validator2, Validator3 validator3) {
    return Arrays.asList(validator1, validator2, validator3);
}

并将列表 bean 注入为 --

@Autowired("validators")
private List<Validator> validators;

查看此页面以获得详细示例 - https://www.baeldung.com/spring-injecting-collections

这可能不是执行此操作的最佳方法。 根据我目前对 Spring 的理解,我会这样做。

概括:

  1. 为每个实现集合创建一个 bean 方法。 在您的情况下,为包含 Validator1 和 Validator2 的List<Validator>创建一个 bean 方法,并创建第二个包含 Validator2 和 Validator3 的List<Validator>
  2. 使用@Qualifier 注入所需的列表。

代码应该是这样的:

@Configuration
public class ValidatorLists
{
    private void getAndAddBean(
        final ApplicationContext applicationContext,
        final List<Validator> list,
        final String beanName)
    {
        final Validator bean;

        bean = applicationContext.getBean(beanName);
        if (bean != null)
        {
            list.add(bean);
        }
    }

    @Bean("ValidatorList1")
    public List<Validator> validatorList1(final ApplicationContext applicationContext)
    {
        Validator bean;
        final List<Validator> returnValue = new LinkedList<>();

        getAndAddBean(applicationContext, returnValue, "ValidatorImpl1");
        getAndAddBean(applicationContext, returnValue, "ValidatorImpl2");
        
        return returnValue;
    }

    @Bean("ValidatorList2")
    public List<Validator> validatorList2(final ApplicationContext applicationContext)
    {
        Validator bean;
        final List<Validator> returnValue = new LinkedList<>();

        getAndAddBean(applicationContext, returnValue, "ValidatorImpl2");
        getAndAddBean(applicationContext, returnValue, "ValidatorImpl3");
        
        return returnValue;
    }
}

然后通过限定符引用列表。

    @Autowired
    @Qualifier("ValidatorList1")
    private List<Validator> validators;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM