Spring 是一个很优秀的基于Java的轻量级开源框架,为了解决企业级应用的复杂性而创建的,Spring不仅可用于服务器端开发,从简单性、可测试性和松耦合性的角度,任何java应用程序都可以利用这个思路进行开发,Spring的核心就是控制反转(Inversion of Control,IoC和 面向切面(Aspect Oriented Programming,AOP

 

控制反转(IoC)

控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup),依赖注入应用比较广泛。

 

IoC最大的好处是什么?

因为把对象生成放在了XML里定义,所以当我们需要换一个实现子类将会变成很简单(一般这样的对象都是实现于某种接口的),只要修改XML就可以了,这样我们甚至可以实现对象的热插拔(有点像USB接口和SCSI硬盘了)。

IoC中最基本的Java技术就是“反射”编程。反射又是一个生涩的名词,通俗的说反射就是根据给出的类名(字符串)来生成对象,这种编程方式可以让对象在生成时才决定要生成哪一种对象。反射的应用是很广泛的,像Hibernate、Spring中都是用“反射”做为最基本的技术手段。

在过去,反射编程方式相对于正常的对象生成方式要慢10几倍,这也许也是当时为什么反射技术没有普遍应用开来的原因。但经SUN改良优化后,反射方式生成对象和通常对象生成方式,速度已经相差不大了(但依然有一倍以上的差距)。

 

IoC最大的缺点是什么?

1)生成一个对象的步骤变复杂了(事实上操作上还是挺简单的),对于不习惯这种方式的人,会觉得有些别扭和不直观。

2)对象生成因为是使用反射编程,在效率上有些损耗。但相对于IoC提高的维护性和灵活性来说,这点损耗是微不足道的,除非某对象的生成对效率要求特别高。

3)缺少IDE重构操作的支持,如果在Eclipse要对类改名,那么你还需要去XML文件里手工去改了,这似乎是所有XML方式的缺陷所在。

总的来说,Spring是一个分层的Java轻量级框架。

 

 

控制反转 (IoC) 

利用某种技术实现低耦合,对象之间相互的依赖关系是通过被动的方式传递进来,而不是对象主动进行另外对象的使用和查找,就是说控制权交给了容器,在初始化的时候,容器将实例化好的对象不用请求就主动传递过来,开发过程中不用进行任何的实例化对象就可以使用对象的方法,使用起来也感觉更加的轻松,所有的对象在Spring中都是一个bean,Spring提供了一种完善的javabean的依赖管理,实际上就是常说的依赖注入,是通过依赖注入的方式实现了控制反转的操作。

 

面向切面(AOP) 

通过分离应用程序的业务逻辑和系统级服务,进行高内聚性的开发,应用对象只完成自己该完成的业务逻辑操作,其他的完全不必考虑,例如系统日志或其他事务等系统服务级操作对象完全不必关心,这样模块化更加清晰,更加适用于逻辑复杂的业务系统。

AOP(Aspect Oriented Programming,面向切面编程),通过 预编译方式 运行期动态代理 实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,提高代码的灵活性和可扩展性,AOP可以说也是这种目标的一种实现。在Spring中提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

主要功能: 日志记录,性能统计,安全控制,事务处理,异常处理等等。

主要意图: 将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

 

刚接触Spring时会出现很多不好理解的概念,下面从一个最简单的例子开始,进入Spring的学习,让Spring更加的形象。

Spring 官网: http://spring.io

 

首先看一下web.xml,通过查看log4j的日志可以发现在服务器启动时applicationContext.xml是先于Spring3-servlet.xml加载,因此applicationContext.xml中已经注册到BeanFactory的bean在Spring3-servlet.xml也是可以使用的,比如在applicationContext.xml中通过context:component-scan扫描了service和dao包,而在Spring3-servlet.xml只扫描了web包,但web包中的Controller依然被注入了Service。

web.xml 各个标签的加载顺序:context-param -> listener -> filter -> servlet

 

1、首先,项目结构

maven-build-simple-example-of-spring-mvc-project-01

总结:主要是将配置文件配置好之后就不会有什么问题了。

在阅读《Maven实战》这本书的时候可以知道有一章是讲解关于继承和聚合的知识,这里主要的是Maven构建SpringMVC项目,所以DAO等这些都写到一起了。因为我也没有只用Maven进行过一个完整项目的实践,所以独立模块开发+聚合可以参考《Maven实战》这本书上面的示例讲解。作为初学者,有很多的东西要学。

附源代码地址:点击打开链接

 

Spring MVC 项目配置文件及代码如下:

2、pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>MavenTest</groupId>
	<artifactId>tan.maven.Springmvc</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>tan.maven.Springmvc Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<Springversion>3.1.1.RELEASE</Springversion>
		<junitversion>3.8.1</junitversion>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junitversion}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-aop</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-asm</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-aspects</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-beans</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-context</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-context-support</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-core</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-expression</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-jdbc</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-jms</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-orm</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-oxm</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-tx</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-web</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-webmvc</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.Springframework</groupId>
			<artifactId>Spring-test</artifactId>
			<version>${Springversion}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>

		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.1</version>
		</dependency>

		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1</version>
		</dependency>
	</dependencies>

	<build>
		<finalName>tan-Springmvc-book</finalName>
	</build>
</project>

 

3、web.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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">
	<display-name></display-name>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>

	<!-- Spring的log4j监听器 -->
	<listener>
		<listener-class>org.Springframework.web.util.Log4jConfigListener</listener-class>
	</listener>

	<!-- 核心控制器 -->
	<servlet>
		<servlet-name>book</servlet-name>
		<servlet-class>org.Springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/applicationContext.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<listener>
		<listener-class>org.Springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<servlet-mapping>
		<servlet-name>book</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

 

4、applicationContext.xml 配置

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

	<mvc:annotation-driven />
	<context:component-scan base-package="com.tan.*" />

	<bean class="org.Springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/" />
		<property name="suffix" value=".jsp" />
	</bean>

</beans>

 

 

5、model:book.java

package com.tan.model;

public class Book {
	private int id;
	private String name;
	private String author;

	public Book() {
	}

	public Book(int id, String name, String author) {
		super();
		this.id = id;
		this.name = name;
		this.author = author;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

}

 

 

6、Dao:bookDao.java

package com.tan.dao;

import org.Springframework.stereotype.Component;

import com.tan.model.Book;

@Component
public class BookDao {

	// 模拟数据库操作  
	public void add(Book book) {
		System.out.print("Add");
	}

	public void update(Book book) {
		System.out.print("Update");
	}
}

 

 

7、Service:BookService.java

package com.tan.service;

import javax.annotation.Resource;

import org.Springframework.stereotype.Component;

import com.tan.dao.BookDao;
import com.tan.model.Book;

@Component
public class BookService {

	private BookDao bookDao;

	public BookDao getBookDao() {
		return bookDao;
	}

	@Resource
	public void setBookDao(BookDao bookDao) {
		this.bookDao = bookDao;
	}

	public void add(Book book) {
		bookDao.add(book);
	}

	public void update(Book book) {
		bookDao.update(book);
	}

}

 

 

8、controller:BookController.java

package com.tan.controller;

import javax.annotation.Resource;

import org.Springframework.stereotype.Controller;
import org.Springframework.web.bind.annotation.RequestMapping;

import com.tan.model.Book;
import com.tan.service.BookService;

@Controller
@RequestMapping("/book.do")
public class BookController {

	private BookService bookService;

	@RequestMapping(params = "method=add")
	public String add(Book book) {
		System.out.println("bookname:" + book.getName());
		System.out.println("author:" + book.getAuthor());
		bookService.add(book);
		return "success";
	}

	@RequestMapping(params = "method=update")
	public String update(Book book) {
		bookService.update(book);
		return "success";
	}

	public BookService getBookService() {
		return bookService;
	}

	@Resource
	public void setBookService(BookService bookService) {
		this.bookService = bookService;
	}
}

 

 

9、index.jsp

<html>
<body>
	<h2>Add Book</h2>
	<form method="post"
		action="<%=request.getContextPath()%>/book.do?method=add">
		bookname:<input type="text" name="name" id="name"> author:<input
			type="text" name="author" id="author"> <input type="submit"
			value="Add">
	</form>
</body>
</html>

 

10、success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'success.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
</head>

<body>
	Success!
	<br>
</body>
</html>

 

 

参考推荐

spring完整demo实例

最简单的Spring-mvc入门示例

使用Maven构建Spring MVC项目的简单示例

Spring MVC 详细示例实战 (详细)

 

Spring 具体分析applicationContext.xml和Spring3-servlet.xml