简体   繁体   English

Spring MVC:servlet中忽略了自动装配

[英]Spring MVC: autowire ignored in servlets

For some reasons, I can autowire in my controllers but not in a servlet I created. 由于某些原因,我可以在控制器中自动布线,但不能在我创建的servlet中自动布线。

This is the top part of my servlet: 这是我的servlet的顶部:

@Component
public class MyServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

    @Autowired
    private CobiService cobiService;

In my web.xml this is the related configuration: 在我的web.xml中,这是相关的配置:

    <servlet>
        <servlet-name>convservlet</servlet-name>
        <servlet-class>com.gim.servlets.MyServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>convservlet</servlet-name>
        <url-pattern>/MyServlet</url-pattern>
    </servlet-mapping>

And this is the way I tell spring to scan for components: 这就是我告诉spring扫描组件的方式:

    <context:component-scan base-package="com.gim" />

For some reason my autowired object cobiService is null. 由于某种原因,我的自动装配对象cobiService为null。 Did I forget anything? 我忘记了什么吗? What should I change? 我应该改变什么?

Servlets are not managed by Spring, they are managed by the Servlet container (like Tomcat). Servlet不是由Spring管理的,而是由Servlet容器(如Tomcat)管理的。 Therefore Spring cannot inject dependencies into Servlets in a normal Spring way. 因此,Spring无法以正常的Spring方式将依赖项注入Servlet。 You can however do something like the following: 但是,您可以执行以下操作:

public class MyServlet extends javax.servlet.http.HttpServlet {

    private CobiService cobiService;

    @Override
    public void init() throws ServletException {
        super.init();
        ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        cobiService = applicationContext.getBean(CobiService.class);
    }

}

There are two servlets being created. 有两个正在创建的servlet。 One is being created by the servlet container/Java EE container when the application initializes and reads the configured <servlet> tag inside the web.xml file. 当应用程序初始化并读取web.xml文件中配置的<servlet>标记时,servlet容器/ Java EE容器将创建一个。 The other would be created when the Spring IOC container performs its component scanning upon initialization. 另一个将在Spring IOC容器在初始化时执行其组件扫描时创建。

In this case, the first instance is not able to participate in dependency injection because it was not created within the Spring IOC container. 在这种情况下,第一个实例不能参与依赖注入,因为它不是在Spring IOC容器中创建的。 In order to participate in dependency injection, a bean must be managed by the Spring IOC container. 为了参与依赖注入,必须由Spring IOC容器管理bean。 When the servlet container/Java EE container instantiates the servlet it has no knowledge of Spring's IOC container. 当servlet容器/ Java EE容器实例化servlet时,它不了解Spring的IOC容器。

Unfortunately, when a request comes in that satisfies the url-pattern specified in the web.xml file for the servlet, the request is redirected to the first instance created by the servlet container/Java EE container which is not a bean and not a candidate for autowiring. 不幸的是,当收到满足servlet的web.xml文件中指定的url-pattern的请求时,该请求将重定向到servlet容器/ Java EE容器创建的第一个实例,该实例不是bean,也不是候选对象自动接线。

If you were to remove the servlet from web.xml and add a @RequestMapping annotation to the servlet, the second instance (which is an actual bean able to utilize autowiring) would be utilized for requests fullfilling the specified url pattern in the @RequestMapping , however at that point you pretty much have a controller. 如果要从web.xml删除该servlet并向该servlet添加一个@RequestMapping批注,则第二个实例(这是一个能够利用自动装配的实际bean)将用于在@RequestMapping填充指定url模式的请求。但是到那时,您几乎有了一个控制器。

So in summary, my recommendation would be to adhere to Spring conventions and use a controller class. 因此,总而言之,我的建议是遵守Spring约定并使用控制器类。 The controller class will match and exceed the functionality provided by the Servlet. 控制器类将匹配并超过Servlet提供的功能。

You can override your servlet init method, and do 您可以覆盖servlet init方法,然后执行

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext (this);

SpringBeanAutowiringSupport SpringBeanAutowiringSupport

There is no need to do 没必要做

implements javax.servlet.Servlet , since you are extending HttpServlet implements javax.servlet.Servlet ,因为您正在扩展HttpServlet

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM