弹簧动态注塑,工厂般的图案

pfh*_*pfh 15 java spring factory dependency-injection factory-pattern

依赖注入的延续,延迟注射实践.我有Main课程:

package test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Scanner;

@Component
public class Main {
    @Autowired
    private StringValidator stringValidator;

    @Autowired
    private StringService stringService;

    @Autowired
    private ValidationService validationService;

    public void main() {
        scanKeyboardCreateLists();

        stringValidator.validate();

        final List<String> validatedList = stringValidator.getValidatedList();
        for (String currentValid : validatedList) {
            System.out.println(currentValid);
        }
    }

    private void scanKeyboardCreateLists() {
        //Let's presume the user interacts with the GUI, dynamically changing the object graph...
        //Needless to say, this is past container initialization...
        Scanner scanner = new Scanner(System.in);
        int choice = scanner.nextInt();

        //Delayed creation, dynamic
        if (choice == 0) {
            stringService.createList();
            validationService.createList();
        } else {
            stringService.createSecondList();
            validationService.createSecondList();
        }
    }

    public static void main(String[] args) {
        ApplicationContext container = new ClassPathXmlApplicationContext("/META-INF/spring/applicationContext.xml");
        container.getBean(Main.class).main();
    }
}
Run Code Online (Sandbox Code Playgroud)

并且根据用户交互动态创建对象图.我解决了应用程序耦合,允许我非常简单地测试它.此外,由于列表是由容器维护的,因此该应用程序(以及其他所有应用程序)的动态特性是无关紧要的,因为可以在应用程序需要它们时随时请求它们,从而维护它们的元素.

其余的代码在这里:

package test;

import java.util.List;

public interface Stringable {
    List<String> getStringList();
}

package test;

import org.springframework.stereotype.Component;

import java.util.ArrayList;

@Component
public class StringList extends ArrayList<String> {
}

package test;

import org.springframework.stereotype.Component;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;

@Component
public class StringService implements Stringable {

    private List<String> stringList;

    @Inject
    public StringService(final ArrayList<String> stringList) {
        this.stringList = stringList;
    }

    //Simplified
    public void createList() {
        stringList.add("FILE1.txt");
        stringList.add("FILE1.dat");
        stringList.add("FILE1.pdf");
        stringList.add("FILE1.rdf");
    }

    public void createSecondList() {
        stringList.add("FILE2.txt");
        stringList.add("FILE2.dat");
        stringList.add("FILE3.pdf");
        stringList.add("FILE3.rdf");
    }

    @Override
    public List<String> getStringList() {
        return stringList;
    }
}

package test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class StringValidator {
    private List<String> stringList;
    private List<String> validationList;

    private final List<String> validatedList = new ArrayList<String>();

    @Autowired
    public StringValidator(final ArrayList<String> stringList,
                           final ArrayList<String> validationList) {
        this.stringList = stringList;
        this.validationList = validationList;
    }

    public void validate() {
        for (String currentString : stringList) {
            for (String currentValidation : validationList) {
                if (currentString.equalsIgnoreCase(currentValidation)) {
                    validatedList.add(currentString);
                }
            }
        }
    }

    public List<String> getValidatedList() {
        return validatedList;
    }
}

package test;

import java.util.List;

public interface Validateable {
    List<String> getValidationList();
}

package test;

import org.springframework.stereotype.Component;

import java.util.ArrayList;

@Component
public class ValidationList extends ArrayList<String> {
}

package test;

import org.springframework.stereotype.Component;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;

@Component
public class ValidationService implements Validateable {

    private List<String> validationList;

    @Inject
    public ValidationService(final ArrayList<String> validationList) {
        this.validationList = validationList;
    }

    //Simplified...
    public void createList() {
        validationList.add("FILE1.txt");
        validationList.add("FILE2.txt");
        validationList.add("FILE3.txt");
        validationList.add("FILE4.txt");
    }

    public void createSecondList() {
        validationList.add("FILE5.txt");
        validationList.add("FILE6.txt");
        validationList.add("FILE7.txt");
        validationList.add("FILE8.txt");
    }

    @Override
    public List<String> getValidationList() {
        return validationList;
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有人知道如何解决方法调用createList()或createSecondList() - 而不使用几乎强制设计的构造函数.我在考虑一个工厂,但是对于一个规模更大的项目中的每个班级的工厂来说似乎都不是一个好主意.

就像是:

<bean ... factory-method="..." depends-on="..." lazy-init="..."/>
Run Code Online (Sandbox Code Playgroud)

并在工厂方法实例化该类并调用方法createList().或者像这样调用它,从某种方法 - 再次看起来很糟糕,迫使方法有责任实例化对象图.

我想在运行时解析的运行时依赖项的图片如下:

在此输入图像描述

是否有其他方法可以使用容器来实现动态懒惰的初始化,具体取决于用户交互?

谢谢.

avi*_*iad 10

如果您希望在每次调用相应的getter时动态初始化/填充类的某个成员,则可以尝试查找方法注入.阅读第3.3.4.1 这里.

因此,即使scope=singletone每次访问分配了查找方法的字段时都创建了包含动态成员的类(spring bean容器的缺省值),您将根据查找方法中实现的业务逻辑获取适当的对象. .在您的情况下,列表是一个接口,因此您可以在查找方法中轻松实现验证并返回经过验证的列表.

编辑:

我在Spring文档中找到了更好的例子 - 我认为它非常清楚.看看"3.4.6.1 Lookup方法注入"

配置Main类时,为其List成员分配查找方法- 只要您需要Listbean 的新实例,就会调用它.

祝好运!