A continuación de Dependency injection, delayed injection praxis. Tengo la clase principal:inyección dinámica de resorte, patrón de fábrica
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();
}
}
Y el gráfico del objeto se crea dinámicamente, dependiendo de la interacción del usuario. Resolví el acoplamiento de aplicaciones, lo que me permitió probar esto de manera muy simple. Además, dado que el contenedor mantiene las listas, la naturaleza dinámica de esta aplicación (y de todas las demás) es irrelevante, ya que pueden solicitarse cada vez que la aplicación las necesita, manteniendo sus elementos.
El resto del código está aquí:
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;
}
}
¿Alguien sabe cómo iba a resolver el CreateList llamada al método() o createSecondList() - sin necesidad de utilizar el constructor que prácticamente fuerzas del diseño. Estaba pensando en una fábrica, pero una fábrica para cada clase en un proyecto de una magnitud mayor no parece una buena idea.
Algo así como:
<bean ... factory-method="..." depends-on="..." lazy-init="..."/>
Y en el método de fábrica instancia de la clase y llamar al método CreateList(). O llámelo así, desde algún método, que de nuevo se ve mal, lo que obliga al método a tener la responsabilidad de crear una instancia del gráfico del objeto.
La imagen de las dependencias de tiempo de ejecución que quiero resolver en tiempo de ejecución es abajo:
¿Hay alguna otra manera de que pudiera utilizar el contenedor a achive initalization perezoso dinámica en función de la interacción del usuario ?
Gracias.
No tengo idea de lo que estás preguntando. ¿Qué quiere decir con "_solve_ el método llamado createList() o createSecondList()"? Si tengo razón en lo que estás tratando de hacer (y lo dudo), crearía una clase de fábrica que tenga un método de fábrica (estático?) Que tome el argumento interactivo y cree la lista apropiada, luego inserta un objeto de fábrica de esa clase en su objeto Principal. –
Pensé que lo entenderías por el contexto. No es una gran pregunta escritora. Sí, algo como esto. La pregunta es en negrita. Además de fábrica (estática, por supuesto) y usando extracción/inicialización de los objetos (con inicialización en la clase principal, método "principal"), ¿cómo puedo construir el gráfico de objeto dinámico para no tener que preocuparme por el código de arquitectura? "en mi aplicación. ¿Por qué debería inyectar el objeto de fábrica en su objeto principal? Tendrás mucho trabajo si todas tus clases son dinámicas. Como deberías tener una fábrica en cada clase dinámica. Todavía creo que hay una solución más simple :) – pfh