Spring的一些零碎知识点整理

在Web工程中配置Spring

要想在Web工程中配置Spring,首先需要在工程加入spring-web包,我这里使用的是maven的web工程,pom.xml配置文件配置的依赖如下:

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.14.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.3.14.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.44</version>
        </dependency>
    </dependencies>

然后在工程的web.xml文件中配置Spring的监听器,web.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
  <display-name>Archetype Created Web Application</display-name>

  <!-- 配置Spring的监听器类 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- 配置Spring配置文件的路径 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:app.xml</param-value>
  </context-param>

</web-app>

这里的配置要说明一下,在配置Spring配置文件的路径时,如果你的配置文件放在WEB-INF下是不需要加上 classpath: 前缀的,只需要写上路径即可,例如:

  <!-- 配置Spring配置文件的路径 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/app.xml</param-value>
  </context-param>

完成以上的配置之后,我们先来写一个简单的Servlet,并配置上Spring的注解:

package org.zero01.test;

import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component("login")
@WebServlet("/login")
public class LoginServlet extends HttpServlet{

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

然后写一个测试的Servlet,看看能否从Spring容器中获得实例对象,在web项目中我们可以通过WebApplicationContextUtils类来帮我们获取Spring的管理对象:

package org.zero01.test;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.zero01.pojo.Student;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/test")
public class TestServlet extends HttpServlet {

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 获得web工程中的Spring管理对象
        WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        // 同样的我们可以通过这个管理对象来获得我们需要的实例对象
        LoginServlet loginServlet = (LoginServlet) webApplicationContext.getBean("login");
        Student student = (Student) webApplicationContext.getBean("stu");

        // 先打印一下,看看能否获取到对象
        PrintWriter printWriter = resp.getWriter();
        printWriter.println(loginServlet);
        printWriter.println(student);
    }
}

输出结果如下:

[email protected]
[email protected]

如上,可以看到对象已经成功获取到了,那就代表我们的配置没有问题,这样我们就可以在web项目中愉快的使用Spring了。

简单说明一下WebApplicationContext对象的加载流程:

  • 我们都知道Tomcat启动时会去加载web.xml文件中的配置,而我们在web.xml配置了Spring的监听类以及Spring配置文件的路径
  • 然后Spring的ContextLoaderListener监听类会监听着ServletContext的初始化以及销毁,这一点查看源码即可得知:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.web.context;

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

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
    public ContextLoaderListener() {
    }

    public ContextLoaderListener(WebApplicationContext context) {
        super(context);
    }

    public void contextInitialized(ServletContextEvent event) {
        this.initWebApplicationContext(event.getServletContext());
    }

    public void contextDestroyed(ServletContextEvent event) {
        this.closeWebApplicationContext(event.getServletContext());
        ContextCleanupListener.cleanupAttributes(event.getServletContext());
    }
}
  • 当ServletContext初始化时会调用该监听类的contextInitialized方法,而该方法调用了initWebApplicationContext方法并传递了ServletContext对象,从方法名的字面意思也可以看出这个方法是用于初始化WebApplicationContext对象的
  • 当WebApplicationContext被初始化时,通过ServletContext对象得到了我们在web.xml中配置的初始化参数,也就是Spring配置文件的路径,于是Spring的配置文件也被加载起来了,成功加载后,WebApplicationContext对象也就初始化完成了。如果没被加载起来就会报错,初始化失败
  • WebApplicationContext对象初始化完成后,就会存放在ServletContext的属性里,这里就完成了整个加载流程
  • 但是由于我们不知道键/值是什么,所以我们无法直接在ServletContext里获得WebApplicationContext对象,而是得通过Spring提供的工具类WebApplicationContextUtils来获得

多个Spring配置文件

有些情况下,我们可能需要多个配置文件,每个配置文件配置不同的模块,如下:

当需要将这些配置文件都引入一个总的配置文件时,可以使用以下语句:

<import resource="app-aop.xml"/>
<import resource="app-ioc.xml"/>
<import resource="app-tran.xml"/>

Spring配置属性文件

Spring支持使用属性文件来配置一些参数,但是这种使用属性文件来配置参数的方式用得不多,因为很鸡肋,而且还会导致到处都是属性文件的散乱情况。不过有可能在一些特殊的情况下会用到,所以在此也记录一下,这里通过配置数据源对象的参数来演示一下如何通过Spring配置属性文件:

首先创建一个属性文件dataSourceInfo.properties,文件内容如下:

database.driver=com.mysql.jdbc.Driver
database.url=jdbc:mysql:///school
database.user=root
database.pw=your_password
database.max.pool.size=10
database.min.pool.size=1
database.loginTimeout=2000

然后编辑Spring的配置内容如下:

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       ">

    <!-- 配置属性文件的路径 -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <array>
                <value>datasourceinfo.properties</value>
            </array>
        </property>
    </bean>

    <!-- 配置数据源对象 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
          p:driverClass="${database.driver}"
          p:jdbcUrl="${database.url}"
          p:user="${database.user}"
          p:password="${database.pw}"
          p:maxPoolSize="${database.max.pool.size}"
          p:minPoolSize="${database.min.pool.size}"
          p:loginTimeout="${database.loginTimeout}"
    />

</beans>

测试代码如下:

package org.zero01.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class Test {

    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("app.xml");
        DataSource dataSource = (DataSource) app.getBean("dataSource");

        try {
            Connection connection = dataSource.getConnection();
            System.out.println(connection);
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

打印结果:

[email protected]

从打印结果可以看到,数据源对象已经成功拿出来了。但是从整个配置流程可以看到有了Spring后还使用属性文件来配置参数就有些绕弯子了,这些参数都是可以在Spring配置文件中直接配置的,而且本身Spring的目的之一就是避免存在大量的属性文件。


Spring在web项目中的初始化类

如果你希望在Tomcat服务器启动时,初始化一个类,并调用该类中的某个方法时,那么你就可以通过实现Spring中的两个接口来完成。首先是InitializingBean接口,实现这个接口的类会在Tomcat服务器启动时被初始化并调用其中的afterPropertiesSet方法:

package org.zero01.test;

import org.springframework.beans.factory.InitializingBean;

public class InitBean implements InitializingBean {

    public void afterPropertiesSet() throws Exception {
        System.out.println("我被初始化了 —— InitializingBean");
    }
}

另一个接口是 ApplicationListener ,这个接口的方法有数据源参数,所以这个方法可以完成更多的事情,而且当你有某个逻辑是必须要等到所有的bean都被处理完成之后再执行的话,就适合使用这个接口,因为所有的bean都被处理完成之后这个接口的方法才会被调用:

package org.zero01.test;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

public class AppInit implements ApplicationListener{
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        System.out.println("我被初始化了 —— ApplicationListener");
    }
}

然后需要配置一下这两个类,Spring配置文件内容如下:

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

    <bean class="org.zero01.test.AppInit"/>
    <bean class="org.zero01.test.InitBean"/>

</beans>

完成配置后启动Tomcat服务器,Tomcat服务器启动时输出结果如下:

可以看到,实现 InitializingBean 接口的类比实现 ApplicationListener 接口的类先被初始化。所以它们之间还是有一些区别的,需要根据具体的业务场景来进行使用哪一个接口。


通过实现接口获得ApplicationContext或者BeanFacrory的对象

通过实现接口获得ApplicationContext对象,代码如下:

package org.zero01.test;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class Test implements ApplicationContextAware {

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        LoginServlet loginServlet = (LoginServlet) applicationContext.getBean("login");
    }
}

通过实现接口获得BeanFacrory对象,代码如下:

package org.zero01.test;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

public class Test implements BeanFactoryAware {

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        LoginServlet loginServlet = (LoginServlet) beanFactory.getBean("login");
    }
}

原文地址:http://blog.51cto.com/zero01/2084047

时间: 2024-10-16 06:51:39

Spring的一些零碎知识点整理的相关文章

零碎知识点整理

一.常用用UIImage加载图像的方法有: 1.用imageNamed函数(适用于图片频繁使用场景) [UIImage imageNamed:ImageName]; 用imageNamed的方式加载时,系统会把图像Cache到内存.如果图像比较大,或者图像比较多,用这种方式会消耗很大的内存,而且释放图像的 内存是一件相对来说比较麻烦的事情.例如:如果利用imageNamed的方式加载图像到一个动态数组NSMutableArray,然后将将数组赋予一 个UIView的对象的animationIma

JSP页面开发知识点整理

刚学JSP页面开发,把知识点整理一下. ----------------------------------------------------------------------- JSP语法http://www.runoob.com/jsp/jsp-syntax.html <% 代码片段 %><% out.println("Hello World!"); %> <%! 变量声明 %><%! int i = 0; %> <%= 表

数据库设计教程系列——相关知识点整理

一.教程概述 此数据库设计教程是笔者参考网上资料.相关书籍,以及加上自己多年做数据库设计相关工作的经验积累写就. 数据库设计教程在网上已经有大量类似的资料,并且该领域有不少专业书籍,珠玉在前,心有戚戚. 但这作为唯心六艺之一,我还是希望能够在整理知识的同时,写出自己的一些内容,如果能够对读者 有所帮助,那就最好不过了,谢谢. 本教程主要基于关系型数据库进行讲解,对于维度数据库也会视情况有所涉猎. 下面是整个教程涉及的知识点整理,在撰写教程的过程中,如果有改动,也会调整更新此图. 二.知识点整理

asp.net mvc 3.0 知识点整理 ----- (2).Controller中几种Action返回类型对比

通过学习,我们可以发现,在Controller中提供了很多不同的Action返回类型.那么具体他们是有什么作用呢?它们的用法和区别是什么呢?通过资料书上的介绍和网上资料的查询,这里就来给大家列举和大致的概括下. (1). ActionResult(base):最基本的Action类型,返回其他类型都可以写ActionResult. (2). ContentResult:返回ContentResult用户定义的内容类型. public ActionResult Content() { return

【知识点整理】Oracle中NOLOGGING、APPEND、ARCHIVE和PARALLEL下,REDO、UNDO和执行速度的比较

[知识点整理]Oracle中NOLOGGING.APPEND.ARCHIVE和PARALLEL下,REDO.UNDO和执行速度的比较 1  BLOG文档结构图 2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 系统和会话级别的REDO和UNDO量的查询 ② NOLOGGING.APPEND.ARCHIVE和PARALLEL下,REDO.UNDO和执行速度的比较(重点)   Tips: ① 本文

【Android 面试基础知识点整理】

针对Android面试中常见的一些知识点整理,Max 只是个搬运工,感谢本文中引用文章的各位作者,给大家分享了这么多优秀文章,对于其中的解析,是原作者个人见解,有错误和不准确的地方,也请大家积极指正. 本文将持续更新,同时我也将其放在Github上:Point-of-Android 同时可以看Max的个人博客:海上钢琴师 Android中的异步任务机制 Android中AsyncTak的使用与源码分析 http://blog.csdn.net/bboyfeiyu/article/details/

·DP」知识点整理

一.最长公共子序列(LCS Longest Common  Subsequence) 第一,先说区别,最长公共子串和最长公共子序列是不一样的. 最长公共子串不许是连续的,而最长公共子序列可以是不联系的. 网络上解释的子序列: 一个字符串S,去掉零个或者多个元素所剩下的子串称为S的子序列.最长公共子序列就是寻找两个给定序列的子序列,该子序列在两个序列中以相同的顺序出现,但是不必要是连续的. 例如 X=ABCBDAB Y=BDCABA BCA是X和Y的一个公共子序列,但是不是X和Y的最长公共子序列,

Python--matplotlib绘图可视化知识点整理

Python--matplotlib绘图可视化知识点整理 强烈推荐ipython 原文:http://michaelxiang.me/2016/05/14/python-matplotlib-basic/ 无论你工作在什么项目上,IPython都是值得推荐的.利用ipython --pylab,可以进入PyLab模式,已经导入了matplotlib库与相关软件包(例如Numpy和Scipy),额可以直接使用相关库的功能. 本文作为学习过程中对matplotlib一些常用知识点的整理,方便查找.

asp.net mvc 3.0 知识点整理 ----- (4).HtmlHelper(Html 辅助方法)介绍

在View视图中,Html的类型是System.Web.Mvc.HtmlHelper<T>, 所有的辅助方法都需要和ModelState交互.那么,ModelState是什么呢?它是模型绑定的附属品,并且存有模型绑定期间检测到的所有验证错误.以及用户提交用到来更新模型的原始值.本篇博文,我们主要来介绍下一些常用的html辅助方法的主要作用和使用方法. 1. Html.BeginForm()和Ajax.BeginForm().   Html.BeginForm(): 同于传统的表单提交,主要是生