1. 了解Spring框架

Spring是一个以控制反转(IoC)、面向切面编程(AoP)为核心的轻量级一站式框架。

优点

  • IoC容器将类与类之间的关系以配置文件的形式进行定义,并且负责了对象的整个生命周期(创建、装配、销毁)。因此在开发过程中只需专注于单个类的业务代码,将对象依赖关系交给IoC负责,以此降低了代码之间的在这里插入代码片耦合度。
  • AoP面向切面编程将业务中的相同部分切割出来,并且对这一部分可通用业务进行管理,在适当的时候将其注入到其他业务的适当位置
  • Spring是一个“友好”的框架,它并不排斥其他优秀的框架,并且提供了优秀的整合方案用其他的框架来替代自己的部分模块。这也是大家使用SSH、SSM等架构的重要基础。

Spring模块

springtool项目_java


Spring大体上内含六个模块:

  • Data Access/Integration (数据访问与集成):提供模伴实现了简单的数据库访问方式和方便的事物控制。ORM组件可对Hibernate、Mybaties等持久层框架进行集成。
  • Web:提供了Web相关功能以及对Struts2、SpringMVC的集成。
  • 面向切面编程:AOP和Aspects一起向开发者提供了面向切面编程服务。
  • Instrumentation:提供了为JVM添加代理的功能。
  • Core Container(核心容器):主要包含了控制反转的IOC容器BeanFactory以及基于BeanFactory扩展的应用上下文ApplicationContext。除此还包含了对EL表达式的支持。
  • Test:提供了测试的模块,可以实现单元测试,集成测试等等的测试流程,整合了JUnit或者TestNG测试框架。

2. 创建Spring项目

引用Jar包

Spring jar包下载地址:https://repo.spring.io/libs-release-local/org/springframework/spring/

打开网页后可选择需要的Spring版本

springtool项目_java_02


选择版本后就可以选择下载文件

springtool项目_springtool项目_03

除了这些Jar以外,使用Spring框架还引入一种日志接口Jar和commons-logging的Jar。这里使用log4j。

配置log4j.properties文件

使用log4j需要配置properties文件,系统默认会在classpath目录下查找该文件,因此放置在src文件夹下即可。如果需要将配置文件放置在其他路径下,则需要手动在监听器初始化程序中添加手动启动log4j的代码。

### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

创建Bean类

这里我们创建一个Dog类和一个Person类。

public class Dog {
	private static Logger log = Logger.getLogger(Dog.class);
	public void eat(){
        System.out.println("狗吃骨头");
        log.info("狗吃骨头");
		
	}
}
public class Person {
	private Dog dog;
	
	public void breed(){
        dog.eat();
	}
	
	public void setDog(Dog dog){
        this.dog = dog;
	}
}

添加IOC配置文件

要使用控制反转,需要将类与类之间的依赖关系通过xml文件的方式进行定义。在classpath路径下创建一个名为spring-conf.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" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans  
                           http://www.springframework.org/schema/beans/spring-beans.xsd">
                           
    <!-- 定义Dog类的bean -->                      
    <bean id="dog" class = "cn.org.way.bean.Dog"></bean>
    
    <!-- 定义Person类的bean,并将id为"dog"的bean与Person类的dog属性建立依赖关系 -->
	<bean id="person" class="cn.org.wqy.bean.Person">
        <property name="dog" ref="dog"></property>
	</bean>
</beans>

编写IOC容器启动程序

在定义好类与类之间的依赖关系之后就需要用一个ServletContextListener监听器启动IOC容器。创建一个ServletContextListener的实现类SpringServletContextListener,重写contextInitialized方法,在该方法中启动IOC容器。

public class SpringServletContextListener implements ServletContextListener{
	
	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
		
	}

	@Override
	public void contextInitialized(ServletContextEvent arg0) {
        //从ContextServlet中获取spring-conf.xml文件路径
        ServletContext servletContext = arg0.getServletContext();
        String config = servletContext.getInitParameter("configLocation");
        
        //创建IOC容器并放入ServletContext
        ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
        servletContext.setAttribute("ApplicationContext", ctx);
	}
}

创建Servlet

public class PersonBreedDogServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public PersonBreedDogServlet() {
        super();
        
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		
        ServletContext servletContext = getServletContext();	
		
        ApplicationContext ctx = (ApplicationContext) servletContext.getAttribute("ApplicationContext");
		
        Person person = (Person) ctx.getBean("person");
        person.breed();
        response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
        doGet(request, response);
	}

}

配置web.xml文件

在一个web项目启动时,首先会加载web.xml文件,在这个过程中,会对文件中定义的参数、监听器、过滤器等进行加载,并创建一个ContextServlet对象,该上下文生存于整个项目运行期间,被整个项目共享。关于web.xml的详细说明有一篇做了详尽说明,推荐阅读。(附链接:)

web.xml文件位于WEB-INF路径下,可直接在IDE工具中随项目一并创建。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" 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>spring-demo1</display-name>
  <!-- 设置默认欢迎页面,可设置多个,按顺序检索 -->
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <!-- 系统参数,存放在ContextServlet中 -->
  <context-param>
  	<param-name>configLocation</param-name>
  	<param-value>classpath:\spring-conf.xml</param-value>
  </context-param>
  
  <context-param>
  	<param-name>log4jConfigLocation</param-name>
  	<param-value>WEB-INF\logs\log4j.properties</param-value>
  </context-param>
  
  <!-- 启动监听器 -->
  <listener>
  	<listener-class>cn.org.wqy.listner.SpringServletContextListener</listener-class>
  </listener>
  
  <!-- 加载servlet -->
  <servlet>
  	<servlet-name>personBreedDogServlet</servlet-name>
  	<servlet-class>cn.org.wqy.servlet.PersonBreedDogServlet</servlet-class>
  	<init-param>
  		<param-name>configLocation</param-name>
  		<param-value>classpath:\spring-conf.xml</param-value>
  	</init-param>
  	<load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
  	<servlet-name>personBreedDogServlet</servlet-name>
  	<url-pattern>/PersonBreedDogServlet</url-pattern>
  </servlet-mapping>
  
  <!-- 系统默认webApp.root,若在一个tomcat启动多个项目可能有冲突 -->
  <context-param>
   <param-name>webAppRootKey</param-name>
   <param-value>webApp.root</param-value>
</context-param>
  
</web-app>

编写一个jsp文件

需要编写的程序和配置的文件都准备好了,可以编写一个jsp页面调用servlet进行测试。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	<a href="PersonBreedDogServlet">测试</a>
</body>
</html>

启动项目之后点击页面的“测试”超链接

springtool项目_xml_04


后台显示

springtool项目_java_05


当我们点击页面的“测试”,会调用personBreedServlet,这个servlet会先从IOC容器中获取Person的对象,从后台日志的第一行Returning cached instance of singleton bean ‘person’ 就可以看出。而我们在调用Person对象的breed()方法时未报空指针异常而是正常执行就可以看出,XML文件中配置的类依赖关系成功的将Dog对象注入到了Person的dog属性中。