2014-03-04 14 views
11

Ich verwende Spring 3.1.3 für eine Webanwendung, die XML-Konfiguration mit Komponentenscan verwendet.Warum hat Spring meine @DependsOn-Annotation ignoriert?

Ich erkannte, dass eine der gescannten Komponenten vor einigen anderen initialisiert werden muss. Für alle Klassen, die eine Initialisierung nach dem Konstruieren benötigen, habe ich eine Annotation @PostConstruct für eine Methode.

Um die Abhängigkeitsreihenfolge einzurichten, habe ich '@Component' in '@Component ("configData")' für die Klasse geändert, die vor den anderen erstellt werden muss. Ich fügte dann "@DependsOn (" configData ") 'unmittelbar vor jeder Klassendefinition hinzu, die NACH der Bean" configData "nachher erstellt werden muss.

Von dem, was ich gelesen habe, ist dies alles was ich brauche, um die Abhängigkeit Reihenfolge zu erzwingen.

Ich baute dann alles, setzte meine Haltepunkte und startete die App. Ich erwartete, den Haltepunkt in der Bean "configData" vor jedem der abhängigen Beans zu treffen. Das ist nicht passiert. Der erste Haltepunkt war in der "init" -Methode einer der abhängigen Beans.

Ich habe dann meine "log4j.xml" geändert, um "debug" als Protokollierungsebene für "org.springframework" zu setzen und meinen Test erneut durchzuführen. Das Breakpoint-Verhalten war das gleiche, und meine Protokollierung zeigte keine Debug-Informationen über die Spring-Initialisierung (ich habe das Debugging für die log4j-Initialisierung selbst aktiviert, also habe ich bestätigt, dass DEBUG für "org.springframework" eingestellt war).

Was könnte ich vermissen?

Update:

Wenn es darauf ankommt, sind hier ein paar Skelett Beispiele von dem, was ich hier tue.

@Component("configData") 
public class ConfigData { 
    .... 
    @PostConstruct 
    public void init() { 
     .... 
    } 
} 

@Component 
@DependsOn("configData") 
public class ClassDependentOnConfigData extends BaseClass { 
    .... 
    @Override 
    @PostConstruct 
    public void init() { 
     super.init(); 
     .... 
    } 
} 

Um es zu wiederholen, was ich zur Laufzeit zu finden, ist, dass die „init()“ Methode in „ClassDependentOnConfigData“ wird von Frühling vor dem „init()“ Methode in „ConfigData“ genannt zu werden.

Beachten Sie auch, dass "BaseClass" ein "@Autowired" für "ConfigData" hat.

+0

können Sie die Bean-Definitionen erstellen (Java und/oder XML) der ConfigData Bohne und eine Bohne, die nach initialisiert werden sollen es als ein Beispiel? –

+0

Ok, aber diese werden nur Skelette sein, und was Sie sehen werden, wird aus meiner Beschreibung offensichtlich sein. –

+0

Wenn Sie keine Spring-Debug-Nachrichten sehen, haben Sie überprüft, dass Sie kein globales THRESHOLD-Set haben oder a One for appender? Mit anderen Worten - siehst du andere DEBUG-Nachrichten? –

Antwort

5

(von jemand anderem korrekt ist, aber jetzt Antwort gelöscht)

Der @DependsOn Vertrag garantiert nur, dass die Bohne konstruiert wurde und Eigenschaften festgelegt wurden. Dies garantiert nicht, dass irgendwelche @PostConstruct-Methoden aufgerufen wurden.

Der Weg, dies zum Laufen zu bringen, besteht darin, die Klasse "dependée" (die Klasse, von der andere abhängig sind) die Klasse "InitializingBean" zu implementieren, die die Implementierung der Methode "afterPropertiesSet()" erfordert. Ich habe den ursprünglichen Körper meiner "init()" Methode in diese Methode eingefügt. Ich habe überprüft, dass dies jetzt vor allen Klassen ausgeführt wird, die davon abhängen. Eine andere Sache, die in der ursprünglichen Antwort erwähnt wurde, ist, dass, wenn ich meine "abhängige" Bean in XML definiert und die "init-method" -Eigenschaft verwendet hätte, dies vor irgendeiner der Klassen, die davon abhängen, ausgeführt hätte. Ich habe das nicht überprüft.

+0

Danke für das Hinzufügen der Antwort noch einmal, ich habe für diese Lösung für zwei Tage gesucht! –

4

Ich stieß auch auf das gleiche Problem, aber immer noch nicht richtig gelöst. Als Teil einer Lösung sagt Spring-Dokumentation:

"DependsOn auf Klassenebene hat keine Auswirkungen, es sei denn, Komponenten-Scan wird verwendet."

Dies ist der Grund, warum die @dependsOn Anmerkung keine Wirkung.

Verwandte Themen