#java #spring #spring-boot
#java #spring #spring-boot
Вопрос:
У меня есть два компонента в приложении с весенней загрузкой:
@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.";
}
}
Я создал Shape
экземпляр, используя следующий код:
Shape shape = beanFactory.getBean(Shape.class, "shape");
Но я получил a NullPointerException
в следующей строке:
this.description = shapeService.getDescription();
shapeService
равно нулю. Есть ли какой-либо способ использовать shapeService
конструктор inside Shape
?
Ответ №1:
Проблема в том, что Spring должен создать объект, прежде чем он сможет выполнить над ним внедрение поля. Таким образом, поле, на которое вы ссылаетесь, еще не было установлено Spring, но будет установлено позже, после того, как объект будет полностью сконструирован. Если бы эта строка была в обычном методе, она бы работала.
Чтобы исправить это, вы должны заставить Spring передать ссылку на ваш ShapeService
конструктор вашему конструктору через аргумент конструктора. Измените свой код для вашего Shape
класса, чтобы он выглядел следующим образом:
@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();
}
}
Я предпочитаю ввод аргумента конструктора вместо автозапуска, даже если в этом нет необходимости, как в вашем случае. Внедрение конструктора обычно считается лучшей формой. Вот статья, в которой объясняется, почему