WebApplicationContext

一、先说ServletContext

  javaee标准规定了,servlet容器需要在应用项目启动时,给应用项目初始化一个ServletContext作为公共环境容器存放公共信息。ServletContext中的信息都是由容器提供的。

举例:

通过自定义contextListener获取web.xml中配置的参数

1.容器启动时,找到配置文件中的context-param作为键值对放到ServletContext中

2.然后找到listener,容器调用它的contextInitialized(ServletContextEvent event)方法,执行其中的操作

例如:在web.xml中配置

<context-param>
   <param-name>key</param-name>
   <param-value>value123</param-value>
</context-param>
<listener> 
   <listener-class>com.brolanda.contextlistener.listener.ContextListenerTest</listener-class>
</listener>

配置好之后,在该类中获取对应的参数信息

复制代码

package com.brolanda.contextlistener.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ContextListenerTest implements ServletContextListener {
    
    public void contextDestroyed(ServletContextEvent event) {
        System.out.println("*************destroy ContextListener*************");
    }
    
    @SuppressWarnings("unused")
    public void contextInitialized(ServletContextEvent event) {
        System.out.println("*************init ContextListener*************");
        ServletContext servletContext = event.getServletContext();
        System.out.println("key:"+servletContext.getInitParameter("key"));
    }
    
}

复制代码

执行流程:

  web.xml在<context-param></context-param>标签中声明应用范围内的初始化参数

1.启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: <listener></listener> 和 <context-param></context-param>

2.紧接着,容器创建一个ServletContext(上下文)。在该应用内全局共享。

3.容器将<context-param></context-param>转化为键值对,并交给ServletContext.

4.容器创建<listener></listener>中的类实例,即创建监听.该监听器必须实现自ServletContextListener接口

5.在监听中会有contextInitialized(ServletContextEvent event)初始化方法

              在这个方法中获得ServletContext = ServletContextEvent.getServletContext();
            “context-param的值” = ServletContext.getInitParameter("context-param的键");

6.得到这个context-param的值之后,你就可以做一些操作了.注意,这个时候你的WEB项目还没有完全启动完成.这个动作会比所有的Servlet都要早.换句话说,这个时候,你对<context-param>中的键值做的操作,将在你的WEB项目完全启动之前被执行.

web.xml中可以定义两种参数:

    一个是全局参数(ServletContext),通过<context-param></context-param>

    一个是servlet参数,通过在servlet中声明        <init-param>

                                                                          <param-name>param1</param-name>

                                                                          <param-value>avalible in servlet init()</param-value>   

                                                                    </init-param> 

 

    第一种参数在servlet里面可以通过getServletContext().getInitParameter("context/param")得到

 

    第二种参数只能在servlet的init()方法中通过this.getInitParameter("param1")取得

 

二、spring上下文容器配置

  spring为我们提供了实现ServletContextListener接口的上下文初始化监听器:org.springframework.web.context.ContextLoaderListener

  spring为我们提供的IOC容器,需要我们指定容器的配置文件,然后由该监听器初始化并创建该容器。要求你指定配置文件的地址及文件名称,一定要使用:contextConfigLocation作为参数名称。

复制代码

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml,/WEB-INF/action-servlet.xml,/WEB-INF/jason-servlet.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

复制代码

该监听器,默认读取/WEB-INF/下的applicationContext.xml文件。但是通过context-param指定配置文件路径后,便会去你指定的路径下读取对应的配置文件,并进行初始化。

三、spring上下文容器配置后,初始化了什么?

  既然,ServletContext是由Servlet容器初始化的,那spring的ContextLoaderListener又做了什么初始化呢?

        1、servlet容器启动,为应用创建一个“全局上下文环境”:ServletContext

        2、容器调用web.xml中配置的contextLoaderListener,初始化WebApplicationContext上下文环境(即IOC容器),加载context-param指定的配置文件信息到IOC容器中。WebApplicationContext在ServletContext中以键值对的形式保存

        3、容器初始化web.xml中配置的servlet,为其初始化自己的上下文信息servletContext,并加载其设置的配置信息到该上下文中。将WebApplicationContext设置为它的父容器。

        4、此后的所有servlet的初始化都按照3步中方式创建,初始化自己的上下文环境,将WebApplicationContext设置为自己的父上下文环境。

 

 

       对于作用范围而言,在DispatcherServlet中可以引用由ContextLoaderListener所创建的ApplicationContext中的内容,而反过来不行。

       当Spring在执行ApplicationContext的getBean时,如果在自己context中找不到对应的bean,则会在父ApplicationContext中去找。这也解释了为什么我们可以在DispatcherServlet中获取到由ContextLoaderListener对应的ApplicationContext中的bean。

 

 四、spring配置时:<context:exclude-filter>的使用原因,为什么在applicationContext.xml中排除controller,而在spring-mvc.xml中incloud这个controller

    既然知道了spring的启动流程,那么web容器初始化webApplicationContext时作为公共的上下文环境,只需要将service、dao等的配置信息在这里加载,而servlet自己的上下文环境信息不需要加载。故,在applicationContext.xml中将@Controller注释的组件排除在外,而在dispatcherServlet加载的配置文件中将@Controller注释的组件加载进来,方便dispatcherServlet进行控制和查找。故,配置如下:

 

applicationContext.mxl中:

 <context:component-scan base-package="com.linkage.edumanage">

      <context:exclude-filter expression="org.springframework.stereotype.Controller"    type="annotation" /> 

 </context:component-scan>

 

spring-mvc.xml中:

  <context:component-scan base-package="com.brolanda.cloud"   use-default-filters="false"> 

      <context:include-filter expression="org.springframework.stereotype.Controller"    type="annotation" /> 

 </context:component-scan>

 

 

新建一个 Java Web 项目

1.打开 Eclipse ,在Project Explorer选项卡下面点击右键,选择Web - Dynamic Web Prodect(这一步应该都知道阿!!!)。

newProject.png

2.点击Next。起一个你认为还不错的项目名,注意:命名很重要,把每一次命名都当做给自己孩子起名字一样庄严神圣。

SpringDemo.png

3.没有了,完成。

demoMenu.png

搞到 Spring 框架的 jar 包

无论你用坑蒙拐骗,还是死皮赖脸,只要你搞到 Spring 框架的 jar 包就行。我这里给你个地址,你可以体面的去下载就行了。地址:http://projects.spring.io/spring-framework/
找到适合自己的版本,下载下来保存到合适的位置就可以了,就这么简单。解压后,应该是这样的:

spring4.2.6.png

你看包的命名,你可能就大致明白了这个 jar 包是干嘛的了,接下来就是引入你需要的了。
然后,你要你需要的 jar 包,复制到项目的/WebContent/WEB-INF/lib下,为什么要这么做,下面会说的。

导入 jar 包

记得当年一个学 Java 的朋友抱怨说: Java 每天都在导包,不如 .Net 爽。我现在并不这么认为。
在项目名上,点击右键,Build Path - Configure Bulid Path... - Libraries - Add JARs...,在弹出的框里边找到项目的/WebContent/WEB-INF/lib,这样就看到刚刚你复制过来的 jar 包了。

add-jars.png

配置配置配置

搭建 Spring 框架最重要的步骤应该就是配置了。官网对框架的解释说明如下:

Spring MVC 框架是围绕一个 DispatcherServlet 来设计的,这个 Servlet 会把请求分发给各个处理器,并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染等,甚至还能支持文件上传。处理器是你的应用中注解了 @Controller 和 @RequestMapping 的类和方法,Spring 为处理器方法提供了极其多样灵活的配置。

所以,首先我们应该在/WebContent/WEB-INF/下新建web.xml文件,接下来在这个文件中配置 DispatcherServlet。

<servlet>
    <servlet-name>springMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springMVC</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

还可以配置字符编码,默认启动页面什么的,这里不在配置,具体见示例项目:https://github.com/mafly/SpringDemo/blob/master/WebContent/WEB-INF/web.xml,因为这里是把 DispatcherServlet 命名为springMVC,并且让它在 Web 项目一启动就加载。接下来我们需要在/WebContent/WEB-INF/目录下创建一个springMVC-servlet.xml的Spring配置文件。Spring官方文档上推荐的默认的文件名是[servlet-name]-servlet.xml文件,这里 servlet-name 叫 springMVC ,因此,我新建了一个springMVC-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"               xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
  http://www.springframework.org/schema/util
  http://www.springframework.org/schema/util/spring-util-4.2.xsd
  http://www.springframework.org/schema/context 
  http://www.springframework.org/schema/context/spring-context-4.2.xsd
  http://www.springframework.org/schema/mvc
  http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">

<!-- 使用默认的注解映射 -->
<mvc:annotation-driven />
<mvc:resources location="/" mapping="/index.html" />


<!-- 自动扫描controller包中的控制器 -->
<context:component-scan base-package="cn.mayongfa.api.controller" />
<context:component-scan base-package="cn.mayongfa.controller" />

<!-- 上传文件拦截,设置最大上传文件大小 30M=30*1024*1024(B)=31457280 bytes -->
<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="31457280" />
</bean>

 

具体详见:https://github.com/mafly/SpringDemo/blob/master/WebContent/WEB-INF/springMVC-servlet.xml
我们在web.xml文件中定义的contextConfigLocation,指定要装入的 Spring 配置文件,一般文件都命名为applicationContext.xml,这个文件中我们可以进行扫描类包、读取配置文件、数据源管理、AOP配置、缓存以及消息队列等配置,所以,接下来就新建applicationContext.xml文件。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop.xsd">

<!-- 将多个配置文件读取到容器中,交给Spring管理 -->
<bean id="propertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:global.properties</value>
            <value>classpath:jdbc.properties</value>
        </list>
    </property>
</bean>

<!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 -->
<context:component-scan base-package="cn.mayongfa.common" />
<context:component-scan base-package="cn.mayongfa.service" />
<context:component-scan base-package="cn.mayongfa.dao" />

<!--master 配置数据源 -->
<bean id="masterDataSource" class="com.alibaba.druid.pool.DruidDataSource"
    init-method="init" destroy-method="close">
    <property name="driverClassName">
        <value>${master.jdbc.driverClassName}</value>
    </property>
    <property name="url">
        <value>${master.jdbc.url}</value>
    </property>
    <property name="username">
        <value>${master.jdbc.username}</value>
    </property>
    <property name="password">
        <value>${master.jdbc.password}</value>
    </property>

    ...
</bean>

<!--slave 配置数据源 -->
<bean id="slaveDataSource" class="com.alibaba.druid.pool.DruidDataSource"
    init-method="init" destroy-method="close">
    
            ...
</bean>

<bean id="dataSource" class="cn.mayongfa.service.imp.DynamicDataSource">
    <property name="targetDataSources">
        <map>
            <entry key="slave" value-ref="slaveDataSource" />
        </map>
    </property>
    <property name="defaultTargetDataSource" ref="masterDataSource" />
</bean>

<!-- 配置Jdbc模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 配置事务管理器 -->
...

<!-- 通过AOP配置提供事务增强,让service包下所有Bean的所有方法拥有事务 -->
...

 

上面只是简单的配置,文件并不完整,具体完整项目示例见GitHub:https://github.com/mafly/SpringDemo

到这里,其实我们已经配置完成了,接下来就是新建我们需要的Package包,来实现不同包来完成不同的事儿的。

新增 Package 包

分层的意义及优缺点我这里不在唠叨,按照正常的分层架构一般都会分为 View 层、Action 层、Service 层、Dao 层,这里我们也是这样做的,下面就开始新建包,.Net 下面是叫类库。

package.png

按照这样的方式新建就可以了,具体的架构如下图:
demoLastMenu.png

到这里,搭建 Spring MVC 框架的工作算是完成了。接下来就是配置具体的数据源、缓存、AOP、JMS 这些东西了。祝你好运!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值