• 【spring】在servlet中注入spring的bean,servlet容器和spring容器


    一、Servlet容器

    Servlet的整个生命周期好象都是由Servlet容器来处理的。

    如果把它硬放到Spring容器中去创建,Servlet对象是可被Spring容器建出来,但Servlet容器可能跟本就不知此Servlet存在,因不在它的容器中。

    所以,servlet交给web server来管理,不要交给spring管理。

    二、让Servlet context 加载 spring context,servlet使用spring context中的对象/bean

    在使用spring容器的web应用中,业务对象间的依赖关系都可以用spring-context.xml文件来配置,并且由spring容器来负责依赖对象的创建。

    如果要在servlet中使用spring容器管理业务对象,通常需要使用 WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()) 来获得WebApplicationContext,然后调用WebApplicationContext.getBean("beanName")来获得对象的引用,这实际上是使用了依赖查找来获得对象,并且在servlet代码中硬编码了应用对象的bean名字

    这种方式,相当于把spring容器中的bean加载到了servlet容器中,即把spring中的bean放到web.xml的bean中。

    三、让servlet感知spring中的bean

    为了能在servlet中感知spring中bean,可采用如下步骤来实现:

    1- 将servlet作为bean定义在spring-context.xml文件中,和要应用的bean定义放在一起;

    2- 实现一个代理servlet,该servlet用WebApplicationContext来获得在spring-context.xml中定义的servlet的对象,并将任务委托给spring-context.xml中定义的servlet

    3- 在web.xml中用ContextLoaderListener来初始化spring 的context,同时在代理servlet的定义中用初始化参数来定义spring-context.xml中servlet的bean名字。

    4- 在web.xml中定义代理servlet的mapping.

    利用这种方式就将servlet和业务对象的依赖关系用spring 来进行管理,并且不用在servlet中硬编码要引用的对象名字。

    四、示例代码

    web.xml

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
          <!-- 为了让spring加载znserver-servlet之外的配置文件,需定义servlet监听器ContextLoaderListener -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/server-servlet.xml
                /WEB-INF/server-bean.xml
            </param-value>
        </context-param>    
        <!-- Creates the Spring Container shared by all Servlets and Filters -->
        <!-- 与上面连起来用 ,加载spring容器
            把本地java程序不可用的bean和本地可用的分开放在不同配置文件,为了运行本地java程序-->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        
        <!-- Processes application requests -->
        <!-- 处理应用的请求,/app/..下面 -->
        <servlet>
            <servlet-name>appServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>/WEB-INF/server-bean.xml</param-value><!--server-bean.xml中要有URL处理的bean,比如Controller -->
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>        
        <servlet-mapping>
            <servlet-name>appServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        
        <!-- 启动InitialServlet,初始化应用和几个重要对象 -->
        <servlet>
            <description></description>
            <display-name>ProxyServlet</display-name>
            <servlet-name>proxyServlet</servlet-name>
            <servlet-class>org.ccnt.med.common.DelegatingServletProxy</servlet-class>
            <load-on-startup>2</load-on-startup>
         </servlet>
         <servlet-mapping>
            <servlet-name>proxyServlet</servlet-name>
            <url-pattern>/ProxyServlet</url-pattern>
         </servlet-mapping>

    server-servlet.xml

    <bean id="proxyServlet" class="org.ccnt.med.common.ProxyServlet"/>

    DelegatingServletProxy.java

    public class DelegatingServletProxy extends GenericServlet {
    
        private String targetBean;
        private Servlet proxy;
        
        @Override
        public void service(ServletRequest arg0, ServletResponse arg1)
                throws ServletException, IOException {
            proxy.service(arg0, arg1);
        }
    
        @Override
        public void init() throws ServletException {
            this.targetBean = getServletName();
            getServletBean();
            proxy.init(getServletConfig());
        }
        
        private void getServletBean() {
            WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
            this.proxy = (Servlet)wac.getBean(targetBean);//get proxyBean
        }
    }

    ProxyServlet.java

    public class ProxyServlet extends HttpServlet{
        
        private Logger logger = LoggerFactory.getLogger(ProxyServlet.class);
        
        @Autowired
        private QueryService queryService;
        public void setQueryService(QueryService queryService)
        {
            this.queryService = queryService;
        }
        
        private static final long serialVersionUID = 1L;
        
        /**
         * @see HttpServlet#HttpServlet()
         */
        public ProxyServlet() {
            super();
        }
        
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
        }
    
        @Override
        public void init(ServletConfig config) throws ServletException {
            logger.info("~~~START~~~");
        }
        
    }

    五、总结

    到这都配置好了,可以放心得使用spring mvc了。回忆下流程:

    1、web.xml中设置spring的listener,导入spring-context.xml。

        配置DelegatingServletProxy  servlet

    2、spring-context.xml中配置bean proxyServlet

    3、DelegatingServletProxy.java中,设置代理servlet--proxyServlet

  • 相关阅读:
    读文章论文
    安装并使用SourceMonitor检测代码复杂度
    FindBug安装与使用
    PMD安装与使用
    Checkstyle安装与使用
    文章主题
    GitHub账号
    PICT的安装与使用
    Junit的安装与使用
    SourceMonitor的安装及使用
  • 原文地址:https://www.cnblogs.com/549294286/p/3020709.html
Copyright © 2020-2023  润新知