Spring非Boot项目@Autowired注入字段为null如何排查解决
问题根因
核心原因是非Spring Boot环境整合Vaadin时,@Route标注的路由视图默认由Vaadin框架自行实例化,没有被Spring IoC容器托管。
Spring的@Autowired注入逻辑只会作用在容器自己创建、管理的Bean实例上,既然LoginView是Vaadin通过new关键字创建的,Spring完全感知不到这个实例的存在,自然不会为它注入UiSecurityService依赖:
- 字段注入失效:Spring没有机会给实例的字段赋值
- Setter注入失效:Spring不会主动调用实例的setter方法传值
- 构造器注入报错:Vaadin默认调用视图的无参构造实例化,带参数的构造器无法被Vaadin识别匹配,自然抛出框架异常。
你之前配置的@ComponentScan、@Component注解本身没有问题,只是这些配置只对Spring容器托管的对象生效,没有覆盖到Vaadin自行创建的视图实例。
解决方案
方案1:配置Vaadin与Spring深度整合(推荐,一劳永逸)
让Vaadin将路由视图的实例化权限交给Spring容器,所有视图统一由Spring管理、完成依赖注入,Vaadin路由时直接从容器取已经初始化好的视图实例即可。
- 引入官方非Boot版的Vaadin-Spring整合依赖(注意不要引入spring-boot-starter相关的Vaadin包)
- 替换项目中默认的Vaadin Servlet配置,注册
SpringVaadinServlet作为路由请求的处理Servlet,该Servlet会自动对接Spring上下文,不再自行实例化视图。 - 给所有
@Route标注的视图类添加Spring的Bean注解,同时配置合适的作用域避免状态串扰:
@Route("login") @Component // 标记为Spring管理的Bean @UIScope // Vaadin-Spring提供的UI级作用域,和Vaadin生命周期绑定,避免单例带来的多用户状态冲突 public class LoginView extends VerticalLayout { private LoginOverlay login; @Autowired private UiSecurityService uiSecurityService; public LoginView() { createContents(); } private void createContents() { // 页面布局逻辑 } private void onLoginPressed(LoginEvent e) { // 登录处理逻辑 } }
配置完成后,所有视图的@Autowired注入就会正常生效,不需要改动原有注入逻辑。
方案2:手动从Spring上下文获取依赖(适合临时快速修复)
如果暂时不想调整全局Vaadin整合配置,可以在Vaadin视图的生命周期方法里,手动从Spring容器获取需要的Bean,不需要让视图被Spring托管:
@Route("login") public class LoginView extends VerticalLayout { private LoginOverlay login; private UiSecurityService uiSecurityService; public LoginView() { createContents(); } @Override protected void onAttach(AttachEvent attachEvent) { super.onAttach(attachEvent); // 视图首次附加到UI时,仅初始化一次依赖 if (uiSecurityService == null) { ApplicationContext springCtx = WebApplicationContextUtils .getRequiredWebApplicationContext(VaadinServlet.getCurrent().getServletContext()); uiSecurityService = springCtx.getBean(UiSecurityService.class); } } private void createContents() { // 页面布局逻辑 } private void onLoginPressed(LoginEvent e) { // 登录处理逻辑 } }
注意不要在构造方法里直接获取Bean,构造方法执行时视图还没关联到Vaadin上下文,拿不到ServletContext引用会报空指针。
内容的提问来源于stack exchange,提问作者mackesmilianw
相关产品推荐
相关产品推荐

