Embedding an object using @Value in an abstract class

I have an abstract class in which I try to use the @Value annotation to enter a value from a properties file

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; } } 

I get a NullPointerException since sharedVal is not set. I tried to add the @Component stereo component to the abstract class and still the same.

Is it possible to enter a value in an abstract class this way? If not, how to do it?

+6
source share
2 answers

I think you will find that sharedVal is installed, but you are trying to use it too early in the constructor. The constructor is called (must be called) before Spring enters the value using the @Value annotation.

Instead of processing the value in the constructor, try using the @PostContruct method, for example:

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

(or alternatively implement the Spring InitializingBean interface).

+18
source

Is it possible to enter a value in an abstract class this way?

Abstract classes cannot be created, so nothing can be introduced into an abstract class. Instead, you should enter a value in your specific subclass.

Make sure your particular subclass is marked as @Component stereotype and is a "component scan" on Spring. @Component in an abstract class is not required because it cannot be created.


Update. Finally, I found out that you were trying to access the entered value inside the constructor, but found that the value was not set. This is because Spring will enter the value after the bean is created. Therefore, if the constructor injection is not used, the injected value cannot be accessible inside the constructor. You can use @PostContruct or implement InitializingBean as suggested by Matt.

The following shows if the XML configuration is used:

 <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"> 

Perform a common action using sharedVal inside Parent#postConstruct()

+4
source

Source: https://habr.com/ru/post/950683/


All Articles