java - Spring动态注入(inject),类工厂模式

标签 java spring dependency-injection factory factory-pattern

Dependency injection, delayed injection praxis 的延续.我有主课:

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

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

剩下的代码在这里:

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

有谁知道我将如何解决方法调用 createList() 或 createSecondList() - 不使用几乎强制设计的构造函数。我在考虑建一个工厂,但是在一个更大的项目中为每个类(class)都建一个工厂似乎不是一个好主意。

类似:

<bean ... factory-method="..." depends-on="..." lazy-init="..."/>

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

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

enter image description here

是否有其他方法可以根据用户交互使用容器来实现动态延迟初始化?

谢谢。

最佳答案

如果您希望类的某些成员在每次调用相应的 getter 时动态初始化\填充,您可以尝试查找方法注入(inject)。阅读页。 3.3.4.1 here .

所以即使包含动态成员的类是在 scope=singletone 中创建的(spring bean 容器的默认设置)每次访问分配了lookup 方法的字段时,都会根据lookup 方法内部实现的业务逻辑得到一个合适的对象。在您的情况下,列表是一个接口(interface),因此您可以轻松地在查找方法中实现验证并返回经过验证的列表。

编辑:

我找到了更好的 example在 Spring 文档中 - 我认为这很清楚。 看看《3.4.6.1 Lookup方法注入(inject)》

当您配置 Main类为其List分配一个查找方法member - 只要您需要 List 的新实例,就会调用它。 bean 。

祝你好运!

关于java - Spring动态注入(inject),类工厂模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10429572/

相关文章:

java - 组件在添加时删除图像

java - 从另一个类调用 UIWebView 方法

c# - 我应该如何使用 IoC/依赖注入(inject)来处理我的实体/域对象?

java - 无法使用 cdi : NullPointerException 注入(inject) bean

angular - Angular 2-7 中的 PROVIDER、INJECTOR 和 SERVICE 有什么区别?

Java - 无法打印图像(到纸张/打印机)

java.lang.IllegalStateException : Task already scheduled or cancelled 错误

java - Vaadin Spring (Vaadin 8) 未找到任何分页组件

java - Access-Control-Allow-Origin 是否足以防止 XSRF 攻击?

java - MVC :resources Spring mapping not working