it-swarm.com.de

Injizieren von Beans in eine Klasse außerhalb des von Spring verwalteten Kontexts

Ich bin Endverbraucher eines Produkts meines Unternehmens. Es ist nicht sehr gut für die Integration in Spring geeignet, aber ich bin in der Lage, den Kontext in den Griff zu bekommen und die gewünschte Bean namentlich abzurufen. Ich würde jedoch gerne wissen, ob es möglich war, eine Bean in diese Klasse zu injizieren, obwohl die Klasse nicht von Spring selbst verwaltet wird.

Erläuterung: Dieselbe Anwendung, die den Lebenszyklus einer Klasse MyClass verwaltet, verwaltet auch den Lebenszyklus des Spring-Kontexts. Spring hat keine Kenntnis von der Instanz von MyClass, und ich würde gerne wissen, wie die Instanz für den Kontext bereitgestellt wird, kann die Instanz jedoch nicht im Kontext selbst erstellen.

54
Spencer Kormos

Du kannst das:

ApplicationContext ctx = ...
YourClass someBeanNotCreatedBySpring = ...
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(
    someBeanNotCreatedBySpring,
    AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, true);

Sie können @Autowired und so weiter in YourClass, um Felder anzugeben, die injiziert werden sollen usw.

57
David Tinker

angenommen, Sie haben die folgende Abhängigkeitskette:

A -> B -> C -> x -> y -> Z

A, B, C sind Spring Managed Beans (konstruiert und montiert durch Spring Framework). X, y sind wirklich einfache POJOs, die von Ihrer Anwendung ohne Federunterstützung konstruiert wurden

wenn Sie möchten, dass y mithilfe von spring einen Verweis auf Z erhält, müssen Sie ein Handle für den spring-Anwendungskontext haben

eine Möglichkeit besteht darin, die Schnittstelle ApplicationContextAware zu implementieren. In diesem Fall würde ich vorschlagen, dass entweder A, B oder C diese Schnittstelle implementieren und die applicationContext-Referenz in einem statischen Member speichern.

nehmen wir zum Beispiel die Klasse C:

class C implmenets ApplicationContextAware{
    public static ApplicationContex ac;
     void setApplicationContext(ApplicationContext applicationContext)  {
               ac = applicationContext;
     }
 .............
}

jetzt solltest du in klasse y haben:

(Z)(C.ac.getBean("classZ")).doSomething()

HTH - Yonatan

2
Yonatan Maman

Eine Möglichkeit, eine Bohne in den Frühling zu bringen, obwohl ihre Herstellung extern ist, besteht darin, eine Hilfsklasse zu verwenden, die als @Configuration Bean mit einer Methode (markiert mit @Bean), der die Instanz tatsächlich erstellt und sie über Spring zurückgibt (das an diesem Punkt seine Eigenschaftsinjektion und Proxy-Generierung ausführt).

Ich bin mir nicht ganz sicher, welchen Spielraum Sie benötigen. Mit prototype erhalten Sie an jeder Stelle eine frische Bohne.

@Configuration
public class FooBarMaker {
    @Bean(autowire = Autowire.BY_TYPE)
    @Scope("prototype")
    public FooBar makeAFooBar() {
        // You probably need to do some more work in here, I imagine
        return new FooBar();
    }
}

Sie können Eigenschaften, die für die Herstellung erforderlich sind, in das @Configuration Bohne. (Ich benutze dies, um Instanzen einer Schnittstelle zu erstellen, in denen der Name der zu instanziierenden Klasse zur Laufzeit definiert wird.)

2
Donal Fellows

Eine andere Möglichkeit, dies zu tun, ist die Verwendung von AspectJ. Dies ist die empfohlene Methode zum Einfügen von Spring Beans in nicht verwaltete Objekte, die mit dem Operator new erstellt wurden. Siehe dies für Details:

http://www.javacodegeeks.com/2011/02/domain-driven-design-spring-aspectj.html

1
HDave

Die Suche nach endlosen Kombinationen von Autodraht-Injektionsfrühlingsbohnen in Pojo-Anwendungen, die kontextabhängig sind, Beanaware usw., umkreiste mich hierher, aber dies bot mir keine ausreichend vollständige Lösung.

Dies ist eine viel bessere Implementierung/Anleitung für diese IMO: Ich hoffe, es hilft allen, wie es mir endlich geholfen hat.

Zugreifen auf Spring Beans von außerhalb des Spring-Kontexts

1
user1204808

Wenn Sie ein Objekt außerhalb des Spring-Kontexts erstellen und dieses Objekt für die Injektion in andere Beans verfügbar machen möchten, die Befinden sich im Frühjahrskontext, können Sie den Schritten in dieser Artikel folgen.

Grundsätzlich erstellen Sie einen übergeordneten Anwendungskontext und verschieben Ihr externes Objekt als Singleton in diesen übergeordneten Kontext. Anschließend erstellen Sie den Hauptanwendungskontext (z. B. aus XML-Dateien) mit dem übergeordneten Anwendungskontext als übergeordnetem Element.

Object externalObject = ...
GenericApplicationContext parent = new StaticApplicationContext();
parent.getBeanFactory().registerSingleton( "externalObject", externalObject );
parent.refresh();
ApplicationContext appContext = new ClassPathXmlApplicationContext( ... , parent);
0
GreenGiant