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

谢谢

http://tinyurl.com/nunnyfm

那时必须是 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初始化方法更方便。