2013-07-31 10 views
6

Ich habe eine abstrakte Klasse, in der ich die @Value Anmerkung zu verwenden, versuchen Nullpointer einzuspritzen Wert aus einer Eigenschaftendatei@Value zu abstrakter Klasse Injizieren Eigenschaft mit

public abstract class Parent { 
    @Value ("${shared.val}") 
    private String sharedVal; 

    public Parent() { 
     //perform common action using sharedVal 
    } 

} 

@Component 
public class ChildA extends Parent { 
    Param a1; 
    @Autowired 
    public ChildA (Param a1) { 
     super(); 
     this.a1 = a1; 
    } 
} 

Ich erhalte seit sharedVal nicht gesetzt . Ich habe versucht, @Component stereotype auf die abstrakte Klasse hinzuzufügen und immer noch das Gleiche.

Kann ich auf diese Weise Wert in abstrakte Klasse injizieren? Wenn nicht, wie kann dies erreicht werden?

+1

Wie wird Ihre Unterklasse instanziiert? – MattR

Antwort

18

glaube ich Ihnen die sharedVal finden wird gesetzt wird, aber Sie versuchen, zu früh im Konstruktor zu verwenden. Der Konstruktor wird aufgerufen (muss aufgerufen werden), bevor Spring den Wert unter Verwendung der @Value Annotation eingibt.

Anstatt den Wert im Konstruktor der Verarbeitung, versuchen, eine @PostContruct Verfahren statt, zum Beispiel:

@PostConstruct 
void init() { 
    //perform common action using sharedVal 
} 

(oder alternativ implementieren Spring InitializingBean Schnittstelle).

+2

Am frühesten sollten Sie jeden injizierten Wert in einer Post-Konstrukt-Methode berühren; Der Zustand von Eigenschaften früher im Lebenszyklus ist undefiniert (gut, typischerweise "Null" oder Null, um pedantisch zu sein). –

+0

Danke, habe heute etwas Neues gelernt. – ltfishie

+0

Und wie kann ich den in meiner porperties-Datei definierten Wert erhalten? @Wert ("$ {shared.val}") –

4

Kann ich auf diese Weise Wert in abstrakte Klasse injizieren?

Abstrakte Klassen können nicht instanziiert werden, daher kann nichts in die abstrakte Klasse eingefügt werden. Stattdessen sollten Sie den Wert der konkreten Unterklasse hinzufügen.

Stellen Sie sicher, dass Ihre konkrete Unterklasse als @Component Stereotyp markiert ist und von Frühling "Komponentenscan" ist. @Component für die abstrakte Klasse ist nicht erforderlich, da es nicht instanziiert werden kann.


Update: Ich endlich herausfinden, dass Sie den injizierten Wert innerhalb des Konstruktors zuzugreifen versuchen, fand aber, dass der Wert nicht gesetzt ist. Dies liegt daran, dass Spring den Wert injiziert, nachdem die Bean instanziiert wurde. Wenn also die Konstruktorinjektion nicht verwendet wird, kann auf den injizierten Wert nicht innerhalb des Konstruktors zugegriffen werden. Sie können @PostContruct verwenden oder InitializingBean implementieren, wie von Matt vorgeschlagen.

Nach zeigt an, ob XML-Konfiguration verwendet wird:

<context:property-placeholder location="classpath:xxxxx.properties" ignore-unresolvable="true" /> 


<bean id="parent" class="pkg.Parent" abstract="true" init-method="postConstruct"> 
    <property name="sharedVal" value="${shared.val}" /> 
</bean> 


<bean id="child" class="pkg.ChildA" parent="parent"> 

Führen Sie Ihre gemeinsame Aktion mit sharedVal innerhalb Parent#postConstruct()

+0

Danke. Ich hatte gehofft, dass es einen Weg gibt, es zu tun, da via xml eine Bean als Abstract erstellt werden konnte. Aber das macht Sinn, denn Spring hat keine Möglichkeit, die abstrakte Klasse zu initialisieren, Wert kann nicht injiziert werden. Ich kann nur daran denken, Property-Objekt zum Laden meiner Eigenschaftendatei zu verwenden und den Schlüssel zu erhalten. Ich hatte gehofft, dies zu vermeiden, indem ich die Annotation @Value – ltfishie

+1

Ich denke, diese Antwort ist irreführend - Spring wird tatsächlich Werte für Eigenschaften in abstrakte Basisklassen injizieren, wenn Sie Autowinding verwenden. – MattR

+0

@MattR. Ja . Spring wird den Wert der für die abstrakte Klasse definierten Eigenschaften in die konkrete Unterklasse, jedoch nicht in die abstrakte Klasse einfügen, da die abstrakte Klasse nicht instanziiert werden kann. Bitte lassen Sie mich wissen, welchen Teil meiner Antwort Sie für irreführend halten. –

Verwandte Themen