【问题标题】:Spring autowiring dependency with constructor arguments带有构造函数参数的 Spring 自动装配依赖项
【发布时间】:2021-02-07 14:16:20
【问题描述】:

我创建了一个服务类,TestService,它的构造函数接受一个字符串数组,并有一点逻辑来返回一个长度大于 5 的字符串列表。

如何使用 Strings 参数数组将其注入到我的 Controller 类中?

@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;
    }
}

【问题讨论】:

  • 有一个@Bean,它返回String[]

标签: java spring-boot dependency-injection constructor


【解决方案1】:

我认为这是不可能的。而是注入String[] testStrings holder:

@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());
    }
}

但是,在本例中,将testStrings 作为getStringsOverLength5 方法参数传递似乎更好。

【讨论】:

    【解决方案2】:

    String 或 String[] 不是 bean 类,所以你不能使用构造函数 Autowired 来做到这一点。但是您可以使用 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;
        }
    }
    

    【讨论】:

    • 如果您在代码中调用 setter 方法,则它不是自动装配的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-19
    • 2014-09-29
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 2014-09-03
    • 2013-06-23
    相关资源
    最近更新 更多