1. 了解Spring框架
Spring是一个以控制反转(IoC)、面向切面编程(AoP)为核心的轻量级一站式框架。
优点
- IoC容器将类与类之间的关系以配置文件的形式进行定义,并且负责了对象的整个生命周期(创建、装配、销毁)。因此在开发过程中只需专注于单个类的业务代码,将对象依赖关系交给IoC负责,以此降低了代码之间的
在这里插入代码片
耦合度。 - AoP面向切面编程将业务中的相同部分切割出来,并且对这一部分可通用业务进行管理,在适当的时候将其注入到其他业务的适当位置。
- Spring是一个“友好”的框架,它并不排斥其他优秀的框架,并且提供了优秀的整合方案用其他的框架来替代自己的部分模块。这也是大家使用SSH、SSM等架构的重要基础。
Spring模块
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版本
选择版本后就可以选择下载文件
除了这些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>
启动项目之后点击页面的“测试”超链接
后台显示
当我们点击页面的“测试”,会调用personBreedServlet,这个servlet会先从IOC容器中获取Person的对象,从后台日志的第一行Returning cached instance of singleton bean ‘person’ 就可以看出。而我们在调用Person对象的breed()方法时未报空指针异常而是正常执行就可以看出,XML文件中配置的类依赖关系成功的将Dog对象注入到了Person的dog属性中。