Spring(-Boot) 自动装配对于 naked initializr 项目总是空的
Spring(-Boot) autowiring is always null with naked initializr project
我是 Spring 和 Spring-Boot starter,我刚刚创建了我的第一个 Spring-Vaadin 应用程序。对象的基本保存和加载如何在 CRUD 接口上工作真是太好了。
所以我的问题是,自动连接的映射无法与我创建的服务一起使用。
我的主程序(MainProgramApplication.java)看起来像:
@SpringBootApplication
public class MainProgramApplication {
public static void main(String[] args) {
SpringApplication.run(MainProgramApplication.class, args);
}
}
有问题的 class 是 MainProgramUI.java:
@Widgetset("AppWidgetset")
@SpringUI
public class Imdb2BoerseUI extends UI {
private static final long serialVersionUID = -6573726003150257919L;
private final VerticalLayout masterLayout;
private VerticalLayout resultLayout;
.......
@Autowired
private MediaService mediaService;
public Imdb2BoerseUI() {
mediaService.doSomethring(); //mediaService is null
}
}
所以我真的不知道为什么这个服务总是空的:(
我发现了很多带有 spring 和自动装配注释的例子...我尝试了大多数版本 :D
所以我最后一次尝试是这个(MediaService.java -> MediaServiceImpl.java)
MediaService.java:
@Service
@Configurable
public interface MediaService extends GenericAccessService<MediaObject>{
public List<MediaObject> getItemsBySearchString(String filterString);
}
MediaServiceImpl.java:
public class MediaServiceImpl implements MediaService{
@Autowired
private SearchQueryRepository searchQueryRepository; //works
@Autowired
private MediaObjectRepository MediaObjectRepository;
public MediaServiceImpl() {
doAnything();
}
............
}
并完成主 GenericAccessService 接口:
public interface GenericAccessService<T> {
List<T> searchInDataBase(String filterPrefix, long firstResult);
long countInDataBase(String filterPrefix);
}
所以我的初学者问题是:为什么 mediaService 总是空的?一般Spring教程的用法和spring-boot的用法有什么区别?使用 spring-boot 时有什么要避免的,与一般的 spring 不同吗?
提前致谢。
本
这里是我目前的文件夹结构:
mainProgram
│ MainProgramUI.java
│ MainProgramApplication.java
├───entities
│ MediaObject.java
│ MediaObjectRepository.java
│ SearchQuery.java
│ SearchQueryRepository.java
├───services
│ MediaService.java
│ MediaServiceImpl.java
│ .....
└───suggestion
GenericAccessService.java
.....
编辑
好的,zapl 的答案在那种情况下有效。现在疯了:
我有一些 classes 和一些 CustomComponents 添加到我的 MainUI。其中一个组件有一个正常的构造函数,如:
MyCustomUiComponent(MyCustomVlauesObject a);
但我不想将我的单身人士 class 通过所有 ComponentClasses 传递给 class 我需要它。
在 TopUiComponent.java 中我创建了 MiddleUiComponent.java 的实例,在这个 class 中我创建了很多 BottomUiComponent.java 的对象。
因此,如果我想在 BottomUiComponent.java 中拥有一个由 Spring 管理的服务或常规对象,我必须将它传递给 UI 元素的所有构造函数吗?
所以我附上了我目前的项目状态。在 class MovieComponent.java 中,我想自动装配一个单例 class 'ImageCache'。
但我真的没有让它工作。也许有人可以看一眼然后告诉我解决方案 T_T
谢谢
那时必须是 null
。 Spring 并不像看起来那么神奇。
public Imdb2BoerseUI() {
mediaService.doSomethring(); //mediaService is null
}
那是构造函数,即使有 Spring 的注入,它也是 class 生命周期中的第一个位置。当 Spring 注入字段时,它只能在调用该构造函数后这样做。否则没有它可以设置字段的实体。
你有2个选择:让spring直接在构造函数中注入:
@Autowired
public Imdb2BoerseUI(MediaService mediaService) {
this.mediaService = mediaService;
mediaService.doSomethring(); //mediaService is no longer null
}
或者在 spring 注入字段后进行所有初始化,方法是给 spring 一个准备就绪后调用的方法:
@PostConstruct
private void init() {
mediaService.doSomethring();
}
构造函数注入是最干净的方法(http://olivergierke.de/2013/11/why-field-injection-is-evil/),post初始化方法更方便。
我是 Spring 和 Spring-Boot starter,我刚刚创建了我的第一个 Spring-Vaadin 应用程序。对象的基本保存和加载如何在 CRUD 接口上工作真是太好了。
所以我的问题是,自动连接的映射无法与我创建的服务一起使用。
我的主程序(MainProgramApplication.java)看起来像:
@SpringBootApplication
public class MainProgramApplication {
public static void main(String[] args) {
SpringApplication.run(MainProgramApplication.class, args);
}
}
有问题的 class 是 MainProgramUI.java:
@Widgetset("AppWidgetset")
@SpringUI
public class Imdb2BoerseUI extends UI {
private static final long serialVersionUID = -6573726003150257919L;
private final VerticalLayout masterLayout;
private VerticalLayout resultLayout;
.......
@Autowired
private MediaService mediaService;
public Imdb2BoerseUI() {
mediaService.doSomethring(); //mediaService is null
}
}
所以我真的不知道为什么这个服务总是空的:( 我发现了很多带有 spring 和自动装配注释的例子...我尝试了大多数版本 :D
所以我最后一次尝试是这个(MediaService.java -> MediaServiceImpl.java)
MediaService.java:
@Service
@Configurable
public interface MediaService extends GenericAccessService<MediaObject>{
public List<MediaObject> getItemsBySearchString(String filterString);
}
MediaServiceImpl.java:
public class MediaServiceImpl implements MediaService{
@Autowired
private SearchQueryRepository searchQueryRepository; //works
@Autowired
private MediaObjectRepository MediaObjectRepository;
public MediaServiceImpl() {
doAnything();
}
............
}
并完成主 GenericAccessService 接口:
public interface GenericAccessService<T> {
List<T> searchInDataBase(String filterPrefix, long firstResult);
long countInDataBase(String filterPrefix);
}
所以我的初学者问题是:为什么 mediaService 总是空的?一般Spring教程的用法和spring-boot的用法有什么区别?使用 spring-boot 时有什么要避免的,与一般的 spring 不同吗?
提前致谢。 本
这里是我目前的文件夹结构:
mainProgram
│ MainProgramUI.java
│ MainProgramApplication.java
├───entities
│ MediaObject.java
│ MediaObjectRepository.java
│ SearchQuery.java
│ SearchQueryRepository.java
├───services
│ MediaService.java
│ MediaServiceImpl.java
│ .....
└───suggestion
GenericAccessService.java
.....
编辑
好的,zapl 的答案在那种情况下有效。现在疯了:
我有一些 classes 和一些 CustomComponents 添加到我的 MainUI。其中一个组件有一个正常的构造函数,如:
MyCustomUiComponent(MyCustomVlauesObject a);
但我不想将我的单身人士 class 通过所有 ComponentClasses 传递给 class 我需要它。
在 TopUiComponent.java 中我创建了 MiddleUiComponent.java 的实例,在这个 class 中我创建了很多 BottomUiComponent.java 的对象。
因此,如果我想在 BottomUiComponent.java 中拥有一个由 Spring 管理的服务或常规对象,我必须将它传递给 UI 元素的所有构造函数吗?
所以我附上了我目前的项目状态。在 class MovieComponent.java 中,我想自动装配一个单例 class 'ImageCache'。
但我真的没有让它工作。也许有人可以看一眼然后告诉我解决方案 T_T
谢谢
那时必须是 null
。 Spring 并不像看起来那么神奇。
public Imdb2BoerseUI() {
mediaService.doSomethring(); //mediaService is null
}
那是构造函数,即使有 Spring 的注入,它也是 class 生命周期中的第一个位置。当 Spring 注入字段时,它只能在调用该构造函数后这样做。否则没有它可以设置字段的实体。
你有2个选择:让spring直接在构造函数中注入:
@Autowired
public Imdb2BoerseUI(MediaService mediaService) {
this.mediaService = mediaService;
mediaService.doSomethring(); //mediaService is no longer null
}
或者在 spring 注入字段后进行所有初始化,方法是给 spring 一个准备就绪后调用的方法:
@PostConstruct
private void init() {
mediaService.doSomethring();
}
构造函数注入是最干净的方法(http://olivergierke.de/2013/11/why-field-injection-is-evil/),post初始化方法更方便。