2009-07-28 10 views
8

Ich habe es mit einer Legacy-Code-Basis zu tun, wo eine Klasse, die im Frühling nicht verdrahtet ist, eine Klasse erhalten muss, die verdrahtet im Frühjahr ist. Ich hatte gehofft, eine Factory-Klasse zu erstellen, die beim Start verdrahtet wurde, und dann konnte ich einfach die Methode getInstance() aufrufen, um ein verdrahtetes Objekt zu erhalten. Was ist der beste Weg, dies zu tun?Federdraht eine statische Klasse

Beispiel:

public class LegacyA { 
    public void doSomething() { 
     ... 
     Foo foo = FooFactory.getInstance(); 
     ... 
    } 
} 

public class FooFactory { 
    private static Foo foo; 

    public static Foo getInstance() { 
     if (foo == null) throw new IllegalStateException(); 
     return foo; 
    } 
} 

I FooFactory muß beim Start verdrahtet werden, so dass LegacyA einfach nennen getInstance(), so dass es eine Instanz von Foo zurückgibt (die auch eine Bohne in dem Anwendungskontext definiert ist).

<bean id="legacyA" class="LegacyA"/> 

<bean id="foo" class="Foo"/> 

<!-- I need this bean to be injected with foo so that the FooFactory can return a foo --> 
<bean id="fooFactory" class="FooFactory"/> 

Edit: Ich hatte mein Beispiel ein wenig neu zu arbeiten, wie ich es ein bisschen bekam Confuzzled in meinem eigenen Kopf ...

+0

Wie wird Foo in FooFactory injiziert? Ein Setzer, Konstrukteur, ...? – wds

Antwort

10

Statik wie diese verwenden geht wirklich gegen den Strich des Frühlings IoC, aber wenn Sie wirklich , sie zu benutzen, dann würde ich vorschlagen, einen einfachen Karabinerhaken Schreiben, die die Foo nimmt und spritzt es in die FooFactory, z.B.

public class FooFactoryProcessor implements InitializingBean { 

    private Foo foo; 

    public void setFoo(Foo foo) { 
     this.foo = foo; 
    } 

    public void afterPropertiesSet() throws Exception { 
     Foofactory.setFoo(foo); 
    } 
} 

Und in Ihrem XML:

<bean id="foo" class="Foo"/> 

<bean class="FooFactoryProcessor"> 
    <property name="foo" ref="foo"/> 
</bean> 

Keine Notwendigkeit Foo oder FooFactory

+0

in Bezug auf Ihre statischen Kommentar vereinbart. Ich würde normalerweise nie diesen Weg gehen, aber der Legacy-Code verwendet diese statische Klasse überall und der beste Weg, um dieses neue Feder-Objekt einzuhängen, ohne den bestehenden Code zu brechen, besteht darin, die Aufrufe an die alte statische Klasse zu halten und diese statisch zu haben Klasse verwenden Sie das neue und verbesserte Federdrahtobjekt. – digiarnie

+2

Warum lassen Sie nicht einfach FooFactory direkt verwalten? Sie brauchen nicht wirklich die Abstraktion die ist "FooFactoryProcessor". Sie können FooFactory einen nicht statischen Eigenschaften-Setter hinzufügen, um foo darauf festzulegen. –

+0

Das ist wahr, ja, aber ich habe die geringste Anzahl von Änderungen am Legacy-Code verfolgt, nach denen das OP zu suchen schien. – skaffman

1

Ist die Definition der Bohne als singleton in der Spring-Konfiguration Einsatz Hier ? Sie können es dann in LegacyB injizieren mit Property oder Konstruktor inject (meine Präferenz ist die letztere) und dann ist nur die eine Instanz verfügbar.

BEARBEITEN: Re. Ihre geänderte Frage (!) Ich bin mir nicht sicher, warum Sie Foo nicht einfach wieder als Singleton in Ihre Fabrik injizieren. Beachten Sie auch, dass Sie die Methode getInstance() über die Spring-Konfigurationen verwenden können, indem Sie factory-method verwenden und die Injektion über alle Klassen aufrechterhalten.

+0

Entschuldigung dafür, dass Sie die Frage etwas ändern müssen. Ich merkte erst etwas später, als ich die ganze Frage falsch in meinem Kopf hatte. – digiarnie

+0

Danke für die Köpfe hoch. Das ist kein Problem. Antwort modifiziert entsprechend. –

1

Zusätzlich zu ändern, um skaffman beantworten die Sie Initialisierungsreihenfolge sehr sehr vorsichtig sein müssen.

Bei der Verwendung von Spring-Beans wird nur das Framework automatisch die richtige Reihenfolge der Initialisierung ermitteln. Sobald du jedoch Singleton-Tricks machst, kann das brechen, wenn du nicht vorsichtig bist.

Mit anderen Worten stellen Sie sicher, dass LegacyA nicht ausgeführt werden kann, bevor Anwendungskontext geladen wird.

Verwandte Themen