简体   繁体   English

Spring 与构造函数 arguments 的自动装配依赖关系

[英]Spring autowiring dependency with constructor arguments

I have created a service class, TestService whose constructor takes an array of Strings and has a little logic to return a list of Strings with length greater than 5.我创建了一个服务 class,TestService,它的构造函数接受一个字符串数组,并有一点逻辑来返回一个长度大于 5 的字符串列表。

How do I get about injecting this into my Controller class with the array of Strings argument?如何使用字符串参数数组将其注入到我的 Controller class 中?

@RestController
public class Controller {

    private final TestService testService;

    @Autowired
    public Controller(TestService testService) {
        this.testService = testService;
    }

    @PostMapping("test")
    public List<String> test(@RequestBody TestDTO request) {
        String[] testStrings = request.getTestStrings();

        // I want to run testService.getStringsOverLength5() on testStrings

        List<String> strings = testService.getStringsOverLength5();
        return strings;
    }
}

@Service
public class TestService {

    private final String[] testStrings;

    public TestService(String[] testStrings) {
        this.testStrings = testStrings;
    }

    public List<String> getStringsOverLength5() {
        return Arrays.stream(testStrings)
                .filter(s -> s.length() > 5)
                .collect(Collectors.toList());
    }
}

public class TestDTO {

    private String[] testStrings;

    public TestDTO() {}

    public String[] getTestStrings() {
        return testStrings;
    }

    public void setTestStrings(String[] testStrings) {
        this.testStrings = testStrings;
    }
}

String or String[] is not a bean class, So you can't do it using the constructor Autowired . StringString[]不是 bean class,所以你不能使用构造函数Autowired来做到这一点。 But you can use Setter Autowired like below.但是您可以使用 Setter Autowired ,如下所示。

public class Controller {

    private final TestService testService;

    @Autowired
    public Controller(TestService testService) {
        this.testService = testService;
    }

    @PostMapping("test")
    public List<String> test(@RequestBody TestDTO request) {
        String[] testStrings = request.getTestStrings();

        // Autowired using setter
        testService.setTestStrings(testStrings);
        // I want to run testService.getStringsOverLength5() on testStrings

        List<String> strings = testService.getStringsOverLength5();
        return strings;
    }
}

@Service
class TestService {

    private String[] testStrings;

    public List<String> getStringsOverLength5() {
        return Arrays.stream(testStrings)
                .filter(s -> s.length() > 5)
                .collect(Collectors.toList());
    }
    
    @Autowired(required=false)
    public void setTestStrings(String[] testStrings) {
        this.testStrings = testStrings;
    }
}

I think it is impossible.我认为这是不可能的。 Instead inject String[] testStrings holder:而是注入String[] testStrings持有者:

@Component
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class TestStringsHolder {

    private String[] testStrings;

    public String[] getTestStrings() {
        return testStrings;
    }

    public void setTestStrings(String[] testStrings) {
        this.testStrings = testStrings;
    }
}
@RestController
public class Controller {

    private final TestService testService;
    private final TestStringsHolder holder;

    @Autowired
    public Controller(TestService testService, TestStringsHolder holder) {
        this.testService = testService;
        this.holder = holder;
    }

    @PostMapping("test")
    public List<String> test(@RequestBody TestDTO request) {
        String[] testStrings = request.getTestStrings();
        holder.setTestStrings(testStrings);

        List<String> strings = testService.getStringsOverLength5();
        return strings;
    }
}
@Service
public class TestService {

    private final TestStringsHolder holder;

    public TestService(TestStringsHolder holder) {
        this.holder = holder;
    }

    public List<String> getStringsOverLength5() {
        final String[] testStrings = holder.getTestStrings();

        return Arrays.stream(testStrings)
            .filter(s -> s.length() > 5)
            .collect(Collectors.toList());
    }
}

However, in this example, it seems better to just pass testStrings as getStringsOverLength5 method argument.但是,在此示例中,最好将testStrings作为getStringsOverLength5方法参数传递。

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

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