Injection dynamique de printemps, modèle d'usine
Une continuation de L'injection de dépendance, retard d'injection de la praxis. J'ai la classe Principale:
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();
}
}
Et de l'objet graphique est créé dynamiquement, en fonction de l'interaction de l'utilisateur. J'ai résolu l'application de couplage, ce qui me permet de tester cela très simplement. Aussi, étant donné que les listes sont gérées par le conteneur, la nature dynamique de cette application(et tous les autres) n'est pas pertinente, car ils peuvent être demandés à tout moment les besoins de l'application, le maintien de leurs éléments.
Le reste du code est ici:
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;
}
}
Personne ne sait comment résoudre l'appel de la méthode createList() ou createSecondList() - sans l'aide du constructeur qui assez bien les forces de la conception. Je pensais à une usine, mais une usine pour chaque classe dans un projet de plus grande ampleur ne semble pas être une bonne idée.
Quelque chose comme:
<bean ... factory-method="..." depends-on="..." lazy-init="..."/>
Et à l'usine de la méthode d'instancier la classe et l'appel à la méthode createList().
Ou l'appeler comme ça, d'un peu de méthode, - ce qui est mauvais, forçant la méthode d'avoir la responsabilité d'instancier l'objet graphique.
L'image de l'dépendances d'exécution que je veux résoudre, dans runtime est ci-dessous:
Est-il un autre moyen que je pouvais utiliser le conteneur à archives dynamique paresseux initalization en fonction de l'interaction de l'utilisateur?
Merci.
source d'informationauteur pfh
Vous devez vous connecter pour publier un commentaire.
Si vous souhaitez que certains membres de votre classe dynamique initialisé\renseigné sur tous les appels à la correspondante de lecture, vous pouvez essayer la Méthode de Recherche de l'Injection. Lire pp. 3.3.4.1 ici.
Donc, même si la classe qui contient le membre dynamique a été créée en
scope=singletone
(la valeur par défaut pour le printemps récipient à grains") chaque fois que vous allez au champ qui a une méthode de recherche affecté, vous obtiendrez un objet approprié selon la logique d'entreprise mis en œuvre à l'intérieur de la méthode de recherche. Dans votre cas, la liste est une interface de sorte que vous pouvez facilement mettre en œuvre la validation à l'intérieur de votre méthode de recherche et de retourner une liste validée.Edit:
J'ai trouvé de mieux exemple au Printemps documentation - je pense que c'est très clair.
Jetez un oeil à "3.4.6.1 méthode de Recherche injection"
Lorsque vous configurez le
Main
classe affecter une méthode de recherche à sonList
membres, elle sera appelée à chaque fois que vous avez besoin d'une nouvelle instance de laList
bean.Bonne chance!
Ressort est conçu pour ré-utilisable injection de composants, pas pour les affaires de manipulation de données et de l'injection.
En effet, certaines données sont utilisés dans l'injection de dépendance, mais seulement pour configurer les composants de comportement, de ne pas créer de données de l'entreprise titulaire.
Par la manière, l'option suivante peut être utilisée dans votre cas: merci
BeanFactory
avec BeanFactoryAware interface et l'utilisation du scope="prototype", vous pouvez générer un haricot en invoquantgetBean()
comme dans cet exemple ou de cette autre question: la création de haricot sur demande.Une autre option si vous avez un nombre limité de haricots à préparer est d'utiliser générique bean création de la même façon dépourvues de haricots sont moqués
Considérons maintenant que le Printemps ne jamais ordures collecte des haricots dans son Contexte. Donc c'est risqué pour la consommation de mémoire pour créer des beans Spring pour vos données.
Si votre objectif est différent (je l'espère), peut-être que vous essayez de mettre en œuvre votre propre un multi-locataire de soutien. Spring fournit location dans le cas où vous avez différentes contexte d'entreprise à mettre en œuvre avec des composants spécifiques ou des comportements.
Sonne comme un utilisateur peut choisir de 1..N graphes d'Objets et que vous souhaitez seulement à la charge de celui que l'utilisateur sélectionne à l'exécution. Si les graphiques sont connus au moment de la conception, mais il suffit que l'utilisateur choisit une qu'ils veulent, puis il me semble que vous avez un tas de ApplicationContexts et vous ne voulez charger une ApplicationContext que l'utilisateur sélectionne à l'exécution. Alors pourquoi ne pas simplement définir l'ensemble des ApplicationContexts et ensuite il vous suffit d'instancier le droit à l'exécution. Depuis le Printemps prend en charge Java Config il peut faire sens pour définir ces configs comme des classes Java, de sorte que vous pouvez obtenir de l'héritage et éviter de couper/coller le code.