一个SSM项目的基本配置——从配置文件窥探SSM原理

首先是web.xml配置文件,
一个SSM框架项目,也是Java web项目。
所有的JavaWeb项目,都需要一个web.xml配置文件
一个JavaWeb项目的加载,最先都是从web.xml开始的
在远古时代,无任何框架的时代,使用 jsp + servlet构建项目的时代,web.xml中只需要配置:
Welcome页面、servlet、servlet-mapping、filter、filter-mapping、listener、启动级别等。当然这些配置也都是按需配置的,一个最基本的JavaWeb项目,其实只需要配置以上内容。

所谓框架,其实是在原有项目模型上做一层抽象并封装,将很多重复的部分提取出来,并自动为程序员提供这一部分的功能,那么在这之后程序员只需要在这个基础上做一些特定程序的定制。编程开发将越来越往这个方向发展,例如IDE的自动代码补全,自动生成get/set/hashcode/equals/constructor等方法,这些方法都有固定的写法,自然IDE能够帮程序员生成这些代码,包括lombok这个插件,真是将程序简化到了极致。在这部分也能联想到以后程序员这个岗位会不会被替代掉= = 当然被替代的也是低级的码农,只是以后门槛越来越高,收入也越来越高(不一定,收入会进入资本家的手中),再加上不断涌入的新人,程序员已经要成夕阳产业了,呜呼,危呼!

回到SSM,我们说SSM只是在普通的JavaWeb项目上做了一层封装,提供了一些简化代码的功能。那么它到底是怎么封装的呢,这就涉及到spring的底层原理了,在这时笔者并无这个实力将其描述清楚,所以我们且先跳过实现原理,直谈它在我们的配置文件中的表现。同理,SSM也是遵循servlet jsp那一套的规则,那么它也必须在web.xml中做出相应的配置,只是在SSM项目中将原本的servlet映射配置,交给了springmvc处理,所以在SSM项目中的web.xml中需要将所有的servlet请求交给springmvc处理,springmvc再接着对具体的访问路径进行分发,以下是具体表现:

<!-- web.xml中的配置项 -->
<servlet>
       <servlet-name>springmvc</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <init-param>
              <!-- 配置 springmvc 的配置文件路径 -->
              <param-name>contextConfigLocation</param-name>
              <param-value>classpath:springmvc.xml</param-value>
       </init-param>
       <!-- 跟着容器启动而实例化 -->
       <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
       <servlet-name>springmvc</servlet-name>
       <url-pattern>/</url-pattern>
  </servlet-mapping>

从以上配置实例我们可以验证上面的说法,web.xml中将“/”路径下所有的访问都交给了org.springframework.web.servlet.DispatcherServlet这个类来处理,既然他能接受请求,那么它也当是一个servlet,原始的servlet,在spring源码中可以看到,DispatcherServlet继承自FrameworkServlet继承自HttpServletBean继承自HttpServlet,所以DispatcherServlet是一个根正苗红的servlet类。自此springmvc通过DispatcherServlet类将所有的请求都拦截到自身了,既然是自己的东西,当然可以搞暗箱操作,在springmvc的一通操作下,所有的请求都只需要通过DispatcherServlet这一个类就可达成目标。

再道SSM配置文件在web.xml中的体现,除了上述关于servlet的配置,在原本无框架的web.xml中还需要配置filter过滤器。其实在JavaWeb中一共有三大组件:简单servlet、过滤servlet、监听servlet,具体到程序中的表现就为servlet、filter、listener,所以在底层filter也被解析为一个servlet,当然在springmvc中就可以用普通servlet实现,但是呢一些全局的filter也可以在web.xml中定义这个是不冲突的:

 <!-- 中文乱码过滤器 -->
 <filter>
   <filter-name>characterEncodingFilter</filter-name>
   <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
   <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
   </init-param>
    <init-param>
       <!-- 是否强制编码 true 针对response -->
       <param-name>forceEncoding</param-name>
       <param-value>true</param-value>
    </init-param>
 </filter>
 <filter-mapping>
       <filter-name>characterEncodingFilter</filter-name>
       <url-pattern>/*</url-pattern>
 </filter-mapping>

上面讲了关于原来最基本的JavaWeb项目的配置在SSM项目中的表现,其实上面那部分就是springmvc在web.xml中的体现。SSM项目除了springmvc还有mybatis,作为一个框架,其实mybatis也是对jdbc进行了一次抽象封装,程序员只需要定义接口,并编写SQL语句即可实现之前用jdbc写几十行代码的功能。

讲mybatis在web.xml中的表现前,先说下web.xml中与这两个配置的含义:参考文章中说的

  1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: 和
    2.紧接着,容器创建一个ServletContext(上下文),这个WEB项目所有部分都将共享这个上下文.
    3.容器将转化为键值对,并交给ServletContext.
    4.容器创建中的类实例,即创建监听.
    5.在监听中会有contextInitialized(ServletContextEvent args)初始化方法,在这个方法中获得ServletContext = ServletContextEvent.getServletContext();
    context-param的值 = ServletContext.getInitParameter(“context-param的键”);
    6.得到这个context-param的值之后,你就可以做一些操作了.注意,这个时候你的WEB项目还没有完全启动完成.这个动作会比所有的Servlet都要早.
    换句话说,这个时候,你对中的键值做的操作,将在你的WEB项目完全启动之前被执行.
    7.举例.你可能想在项目启动之前就打开数据库.
    那么这里就可以在中设置数据库的连接方式,在监听类中初始化数据库的连接.
    8.这个监听是自己写的一个类,除了初始化方法,它还有销毁方法.用于关闭应用前释放资源.比如说数据库连接的关闭.

所以JavaWeb中对数据库的配置是由确定的,那么mybatis的配置也自然是由确定的了。
下面给一个例子:

 <context-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>classpath:applicationContext.xml</param-value>
 </context-param>

其实仅仅只是导入了applicationContext.xml这个文件,这个配置就将web.xml中对webContext的配置交给了applicationContext.xml这个文件去处理。

以上就已经将web.xml这个配置文件配好了,从上面我们也可以知道SSM项目最基本的配置配置文件有:web.xml、springmvc.xml、applicationContext.xml。
上面已经讲了关于web.xml的配置详情,接下来讨论下springmvc.xml的配置,见名知意这个文件是用来配置springmvc的,在探讨spring的配置前,先盘点下spring做了那些事?

  1. spring 提供了一系列的注解来简化程序,那么解析这些注释自然而然需要一个驱动,所以在springmvc就有了关于spring annotation的配置;
<!--启用spring的一些annotation(注解) -->
<context:annotation-config/>
<!-- 配置注解驱动 可以将request参数与绑定到controller参数上 -->
<mvc:annotation-driven/>
  1. spring 对servlet进行了一层包装,并将那些由@controller注解修饰的类组装为servlet,那么就需要在组装前将这些被@controller修饰的类全部找出来,于是就有了包扫描的配置;
<!-- 扫描controller类 -->
<context:component-scan  
        base-package="com.suep.ssm.controller"></context:component-scan>

当然上面可以再安全一点:

<!-- 只扫注解标记的类 -->
<context:component-scan base-package="com.suep.ssm" use-default-filters="false">                  <context:include-filter type="annotation" 
            expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
  1. spring 中只需要编写视图名就可映射到视图上,说明spring需要做一个视图名与视图的映射配置。
<!-- 视图解析器定义 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
             <property name="prefix" value="/WEB-INF/views/"/>
             <property name="suffix" value=".jsp"></property>
</bean>
  1. 对于一些全局常量(例如jdbc内的一些配置),spring提供了常量代名,当然也需要配置。
<!-- 添加全局变量 -->
<context:property-placeholder location="classpath:jdbc.properties" />

说一个题外话:spring明明都已经帮我们做好了那么多事,为什么还要我们去配置呢,它不会自己配置吗?
其实这些配置都是用来方便成需要对自己写的代码有主人翁意识,spring退居为工具人,这样程序员对于整个程序的有了一个整体意识,当程序出现了某些出乎意料的错误时,这时候程序员就能比较快速的定位到问题。那么问题又来了:它不会自己解决这些异常吗 当然在我们写配置,感到不厌烦的时候确实会这么去想。人啊,天生懒惰,总是希望别人帮他把所有的事都做了,然后功劳都归自己。天真,这能行吗?目前spring确实不能做到那一步,但是要真做到那一步了,还需要你这个低级码农来搬砖?想屁吃,你只会丢掉工作然后没饭吃。给你这个搬砖的机会还得看人高级程序员的脸色,心情好了赏你口饭吃,就快谢主隆恩吧。噗嗤,聊远了聊远了。

接下来探讨applicationContext.xml文件内的配置选项,之前说我们现在用到applicationContext.xml主要是为了配置mybatis,好让mybatis帮我们干活,然后功劳归我们。mybatis是对jdbc做了一层封装,让我们通过定义一个dao层接口再到mybatis mapper文件中写一些sql语句就实现了对数据库的操作。那么之前我们用jdbc操作数据库的那些步骤都到哪去了?(废话当然是mybatis帮我们做了)mybatis是怎么知道我们要对那个数据库做那些操作呢?在没配置之前mybatis当然不知道该对那个数据库做那个操作。嘿嘿,还是得靠我们码农去搬砖了,我们不搬砖,mybatis啥都不知道呢。哈哈,自豪吧,码农!
言归正传,mybatis要对jdbc封装首先得知道四大要素:jdbc驱动类名、数据库url、用户名、密码。

<!-- 配置连接数据源 
     destroy-method="close" 当容器关闭的时候,自动调用bean的方法 
     这是配置的是数据源连接池,用的是<u>dbcp</u>;c3p0,
-->
<bean name="datasource" class="org.apache.commons.dbcp2.BasicDataSource"
     destroy-method="close"
>
     <!-- 配置四大要素 -->
     <property name="driverClassName" value="${jdbc.driver}"></property>
     <property name="url" value="${jdbc.url}"></property>
     <property name="username" value="${jdbc.username}"></property>
     <property name="password" value="${jdbc.password}"></property>
</bean>

我们做开发时用的环境和实际生产的环境当然不一样,数据库也不一样,那么程序就可能经常要对数据源的参数进行修改,当然全局都去修改也行,只要不嫌麻烦。当然我是嫌麻烦的(什么是高级程序员? 此处战术后仰),所以这里也需要加载以下全局常量:

<context:property-placeholder location="database.properties"/>

除了要创建数据库的连接池,mybatis当然得要找到它的宝贝——mapper文件

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
             <property name="basePackage" value="com.suep.ssm.mapper"></property>
</bean>

好了mybatis已经可以连接数据库并操作它了,但,我们怎么调用mybatis呢?
mybatis提供了一个核心工厂类——SqlSessionFactory用于生产各种Dao层实现类的实例

<!-- 配置SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 注入数据源 -->
    <property name="dataSource" ref="dataSource"></property>
    <!-- 注入别名配置 -->
    <property name="typeAliasesPackage" value="com.ssmDemo.pojo"></property>
    <!-- 映射资 源路径 -->
    <property name="mapperLocations" value="classpath*:mappers/**/*.xml"></property>
</bean>

怎么配置了一遍SSM配置文件,就感觉自己已经掌握了SSM的原理呢?

懂了,我就是 高 级 程 序 员 ~ !

想屁呢?

下一篇:spring实现原理窥探

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值