Reputation: 27574
I have two beans in a spring-boot application:
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class Shape {
@Resource
private ShapeService shapeService;
private String name;
private String description;
public Shape(String name) {
this.name = name;
this.description = shapeService.getDescription();
}
}
@Service
public class ShapeService {
public String getDescription() {
return "This is a shape.";
}
}
I created the Shape
instance using the following code:
Shape shape = beanFactory.getBean(Shape.class, "shape");
But I got a NullPointerException
on the following line:
this.description = shapeService.getDescription();
shapeService
is null. Is there any way to use shapeService
inside Shape
's constructor?
Upvotes: 0
Views: 172
Reputation: 23089
The problem is that Spring has to create an object before it can do field injection on it. So the field you are referencing hasn't been set yet by Spring, but will be later on, after the object is fully constructed. If that line were in a regular method, it would work.
To fix this, you have to have Spring pass the reference to your ShapeService
to your constructor via a constructor argument. Change your code for your Shape
class to look like this:
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class Shape {
private ShapeService shapeService;
private String name;
private String description;
public Shape(String name, ShapeService shapeService) {
this.name = name;
this.shapeService = shapeService;
this.description = shapeService.getDescription();
}
}
I prefer constructor argument injection over autowiring even if it isn't necessary, like it is in your case. Constructor injection is generally considered to be better form. Here's an article that explains why
Upvotes: 1