Vaadin Spring 在视图中启动@autowired 字段returns null
Vaadin Spring Boot @autowired field returns null in a view
首先,由于我是 spring 引导生态系统的新手,请原谅我的问题。在我的应用程序中,我有一个 vaadin 页面,我想在其中使用存储库将用户详细信息提交给数据库。在我看来 class,我已将它们添加为 @autowired 字段,但是,在 运行 期间,我看到它们的值为 运行,因此操作失败。我知道要从@autowired 中受益,不应在构建期间新创建实例,但我无法弄清楚我应该如何自己做。这是我的 classes:
@SuppressWarnings("serial")
public class LoginAwareComposite extends Composite<Div> {
@Autowired
private ApplicationEventPublisher publisher;
public LoginAwareComposite() {
}
@Override
protected void onAttach(AttachEvent event) {
super.onAttach(event);
UserCredentials userPrincipal = UI.getCurrent().getSession().getAttribute(UserCredentials.class);
if (userPrincipal != null) {
// --- NOT LOGGED IN
UI.getCurrent().navigate(AddressBookManagementView.class);
}
}
}
@SuppressWarnings("serial")
@Route(value = "account")
@Theme(value = Lumo.class, variant = Lumo.LIGHT)
public class AddressBookManagementView extends LoginAwareComposite {
private VerticalLayout pageLayout = new VerticalLayout();
public AddressBookManagementView() {
getContent().setSizeFull();
getContent().add(initPage());
}
private Component initPage() {
pageLayout.getStyle().set("padding-left", "0px");
pageLayout.getStyle().set("padding-bottom", "0px");
pageLayout.getStyle().set("padding-right", "0px");
pageLayout.getStyle().set("overflow", "auto");
pageLayout.setSizeFull();
pageLayout.add(new HeaderLayout(), new BodyLayout(), new FooterLayout());
return pageLayout;
}
}
@SuppressWarnings("serial")
@SpringComponent
public class BodyLayout extends VerticalLayout {
// some fields
@Autowired
EmailRepository emailRepository;
@Autowired
FaxRepository faxRepository;
public BodyLayout() {
init(); //this function inits the view, and eventually inits the on click event for submit button , which then calls my function
}
private void myFunction() {
//here i use the repository entities but they do return null although they are autowired
}
所以发生的事情是,在 BodyLayout 的构造函数中我们调用 init() 函数,该函数用于初始化布局并提供功能按钮等,init 方法中的一个子函数提供使用 myFunction 提交按钮的功能。 MyFuction 使用存储库实体,但它 returns 为空。
由于您使用的是带有 vaadin 的 springboot,因此请确保以下内容:
- 确保像
EmailRepository
一样在存储库界面上使用 @Repository
注释。
- 尝试为您的存储库使用构造函数注入 类 如:
像下面这样尝试:
@SuppressWarnings("serial")
@SpringComponent
@UIScope
public class BodyLayout extends VerticalLayout {
// some fields
private final EmailRepository emailRepository;
private final FaxRepository faxRepository;
@Autowired
public BodyLayout(EmailRepository emailRepository, FaxRepository faxRepository) {
this.emailRepository = emailRepository;
this.faxRepository = faxRepository;
init(); //this function inits the view, and eventually inits the on click event for submit button , which then calls my function
}
private void myFunction() {
//here i use the repository entities but they do return null although they are autowired
}
我能够让它按如下方式工作:
@SuppressWarnings("serial")
@Route(value = "account")
@Theme(value = Lumo.class, variant = Lumo.LIGHT)
@UIScope
@SpringComponent
public class AddressBookManagementView extends LoginAwareComposite {
private VerticalLayout pageLayout = new VerticalLayout();
@Autowired
BodyLayout bodyLayout;
public AddressBookManagementView(BodyLayout bodyLayout) {
this.bodyLayout = bodyLayout;
getContent().setSizeFull();
getContent().add(initPage());
}
private Component initPage() {
pageLayout.getStyle().set("padding-left", "0px");
pageLayout.getStyle().set("padding-bottom", "0px");
pageLayout.getStyle().set("padding-right", "0px");
pageLayout.getStyle().set("overflow", "auto");
pageLayout.setSizeFull();
pageLayout.add(new HeaderLayout(), bodyLayout, new FooterLayout());
return pageLayout;
}
那么BodyLayout就是
@SuppressWarnings("serial")
@UIScope
@SpringComponent
public class BodyLayout extends VerticalLayout {
private final EmailRepository emailRepository;
private final FaxRepository faxRepository;
@Autowired
public BodyLayout(EmailRepository emailRepository, FaxRepository faxRepository) {
this.emailRepository = emailRepository;
this.faxRepository = faxRepository;
init();
}
大约只有 @Route
、布局和 vaadin init 侦听器参与自动依赖注入(即:vaadin spring 集成要求 spring 上下文来构建它们) .如果你这样做 new MyClass()
它 永远不会 参与 DI。使用基于字段的注入 @Autowired
隐藏了这个问题 - 所以使用基于构造函数的注入是“行业标准”。另一种方法是不构建自己的实例,如果你想参与 DI 但要求 spring 上下文为你构建一个实例。
首先,由于我是 spring 引导生态系统的新手,请原谅我的问题。在我的应用程序中,我有一个 vaadin 页面,我想在其中使用存储库将用户详细信息提交给数据库。在我看来 class,我已将它们添加为 @autowired 字段,但是,在 运行 期间,我看到它们的值为 运行,因此操作失败。我知道要从@autowired 中受益,不应在构建期间新创建实例,但我无法弄清楚我应该如何自己做。这是我的 classes:
@SuppressWarnings("serial")
public class LoginAwareComposite extends Composite<Div> {
@Autowired
private ApplicationEventPublisher publisher;
public LoginAwareComposite() {
}
@Override
protected void onAttach(AttachEvent event) {
super.onAttach(event);
UserCredentials userPrincipal = UI.getCurrent().getSession().getAttribute(UserCredentials.class);
if (userPrincipal != null) {
// --- NOT LOGGED IN
UI.getCurrent().navigate(AddressBookManagementView.class);
}
}
}
@SuppressWarnings("serial")
@Route(value = "account")
@Theme(value = Lumo.class, variant = Lumo.LIGHT)
public class AddressBookManagementView extends LoginAwareComposite {
private VerticalLayout pageLayout = new VerticalLayout();
public AddressBookManagementView() {
getContent().setSizeFull();
getContent().add(initPage());
}
private Component initPage() {
pageLayout.getStyle().set("padding-left", "0px");
pageLayout.getStyle().set("padding-bottom", "0px");
pageLayout.getStyle().set("padding-right", "0px");
pageLayout.getStyle().set("overflow", "auto");
pageLayout.setSizeFull();
pageLayout.add(new HeaderLayout(), new BodyLayout(), new FooterLayout());
return pageLayout;
}
}
@SuppressWarnings("serial")
@SpringComponent
public class BodyLayout extends VerticalLayout {
// some fields
@Autowired
EmailRepository emailRepository;
@Autowired
FaxRepository faxRepository;
public BodyLayout() {
init(); //this function inits the view, and eventually inits the on click event for submit button , which then calls my function
}
private void myFunction() {
//here i use the repository entities but they do return null although they are autowired
}
所以发生的事情是,在 BodyLayout 的构造函数中我们调用 init() 函数,该函数用于初始化布局并提供功能按钮等,init 方法中的一个子函数提供使用 myFunction 提交按钮的功能。 MyFuction 使用存储库实体,但它 returns 为空。
由于您使用的是带有 vaadin 的 springboot,因此请确保以下内容:
- 确保像
EmailRepository
一样在存储库界面上使用@Repository
注释。 - 尝试为您的存储库使用构造函数注入 类 如:
像下面这样尝试:
@SuppressWarnings("serial")
@SpringComponent
@UIScope
public class BodyLayout extends VerticalLayout {
// some fields
private final EmailRepository emailRepository;
private final FaxRepository faxRepository;
@Autowired
public BodyLayout(EmailRepository emailRepository, FaxRepository faxRepository) {
this.emailRepository = emailRepository;
this.faxRepository = faxRepository;
init(); //this function inits the view, and eventually inits the on click event for submit button , which then calls my function
}
private void myFunction() {
//here i use the repository entities but they do return null although they are autowired
}
我能够让它按如下方式工作:
@SuppressWarnings("serial")
@Route(value = "account")
@Theme(value = Lumo.class, variant = Lumo.LIGHT)
@UIScope
@SpringComponent
public class AddressBookManagementView extends LoginAwareComposite {
private VerticalLayout pageLayout = new VerticalLayout();
@Autowired
BodyLayout bodyLayout;
public AddressBookManagementView(BodyLayout bodyLayout) {
this.bodyLayout = bodyLayout;
getContent().setSizeFull();
getContent().add(initPage());
}
private Component initPage() {
pageLayout.getStyle().set("padding-left", "0px");
pageLayout.getStyle().set("padding-bottom", "0px");
pageLayout.getStyle().set("padding-right", "0px");
pageLayout.getStyle().set("overflow", "auto");
pageLayout.setSizeFull();
pageLayout.add(new HeaderLayout(), bodyLayout, new FooterLayout());
return pageLayout;
}
那么BodyLayout就是
@SuppressWarnings("serial")
@UIScope
@SpringComponent
public class BodyLayout extends VerticalLayout {
private final EmailRepository emailRepository;
private final FaxRepository faxRepository;
@Autowired
public BodyLayout(EmailRepository emailRepository, FaxRepository faxRepository) {
this.emailRepository = emailRepository;
this.faxRepository = faxRepository;
init();
}
大约只有 @Route
、布局和 vaadin init 侦听器参与自动依赖注入(即:vaadin spring 集成要求 spring 上下文来构建它们) .如果你这样做 new MyClass()
它 永远不会 参与 DI。使用基于字段的注入 @Autowired
隐藏了这个问题 - 所以使用基于构造函数的注入是“行业标准”。另一种方法是不构建自己的实例,如果你想参与 DI 但要求 spring 上下文为你构建一个实例。