文档版本 |
开发工具 |
测试平台 |
工程名字 |
日期 |
做者 |
备注 |
V1.0 |
|
|
|
2016.06.21 |
lutianfei |
none |
- 本文内容
- Spring框架的概述
- Spring的快速入门
- Spring 工厂接口
- 在MyEclipse 配置Spring的xml文件提示
- IoC容器装配Bean(xml配置方式)
- Ioc容器装配Bean(注解方式)
- 在web项目中集成Spring
- Spring 整合 junit4 测试
Spring框架学习路线
- Spring的Ioc
- Spring的AOP , AspectJ
- Spring的事务管理
Spring框架的概述
什么是Spring
Spring是分层的JavaSE/EE full-stack(一站式) 轻量级开源框架html
SUN提供的EE的三层结构:web层、业务层、数据访问层(持久层,集成层)java
- Struts2是web层基于MVC设计模式框架.
- Hibernate是持久的一个ORM的框架.
Spring框架有对三层的一站式解决方案:web
- web层:Spring MVC
- 持久层:JDBC Template
- 业务层:Spring的Bean管理
Spring的出现是为了取代EJB的臃肿、低效、脱离现实spring
Spring的核心
IOC:(Inverse of Control 反转控制)express
AOP : Aspect Oriented Programming 是 面向对象的功能延伸.不是替换面向对象,是用来解决OO中一些问题.apache
Spring的版本
- Spring3.x和Spring4.x Spring4须要整合hibernate4.
Spring优势
- 方便解耦,简化开发
- Spring就是一个大工厂,能够将全部对象建立和依赖关系维护,交给Spring管理

- AOP编程的支持
- Spring提供面向切面编程,能够方便的实现对程序进行权限拦截、运行监控等功能
- 声明式事务的支持
- 只须要经过配置就能够完成对事务的管理,而无需手动编程
- 方便程序的测试
- Spring对Junit4支持,能够经过注解方便的测试Spring程序
- 方便集成各类优秀框架
- Spring不排斥各类优秀的开源框架,其内部提供了对各类优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
- 下降JavaEE API的使用难度
- Spring 对JavaEE开发中很是难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大下降
Spring体系结构
- Spring 框架是一个分层架构,它包含一系列的功能要素并被分为大约20个模块。这些模块分为Core Container、Data Access/Integration、Web、AOP(Aspect Oriented Programming)、Instrumentation和测试部分,以下图所示:

Spring的快速入门
1. 下载Spring的开发包
2. 建立web工程引入相应jar包

3. 建立Spring的配置文件
- 在src下建立一个applicationContext.xml
- 引入XML的约束
- 找到xsd-config.html.引入beans约束
<?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 definitions here -->
</beans>
4. 在配置中配置类
<!-- 经过一个<bean>标签设置类的信息,经过id属性为类起个标识. -->
<bean id="userService" class="cn.itcast.spring3.demo1.HelloServiceImpl"></bean>
5. 建立测试类
- ApplicationContext 应用上下文,加载Spring 框架配置文件
- 加载classpath:
- new ClassPathXmlApplicationContext(“applicationContext.xml”);
- 加载磁盘路径:
- new FileSystemXmlApplicationContext(“applicationContext.xml”);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
@Test
// Spring开发
public void demo2() {
// 建立一个工厂类.
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext(
"applicationContext.xml");
HelloService helloService = (HelloService) applicationContext.getBean(
"userService");
helloService.sayHello();
}

类建立的传统方式
IOC和DI区别
public class A{
private B b;
}
* 继承:is a
* 聚合:
* 汇集:
* 组合:
BeanFactory与ApplicationContext区别

- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
@Test
public void demo4(){
// ClassPathResource FileSystemResource
BeanFactory beanFactory =
new XmlBeanFactory(
new FileSystemResource(
"applicationContext.xml"))</u>;
HelloService helloService = (HelloService) beanFactory.getBean(
"userService");
helloService.sayHello();
}
MyEclipse配置XML提示
Spring框架Bean实例化的方式
- 三种方式实例化Bean
- 构造方法实例化(默认无参数)
- 静态工厂实例化
- 实例工厂实例化
无参数构造方法的实例化
<!-- 默认状况下使用的就是无参数的构造方法. -->
<bean id="bean1" class="cn.itcast.spring3.demo2.Bean1"></bean>
静态工厂实例化 – 简单工厂模式
<!-- 第二种使用静态工厂实例化 -->
<bean id="bean2" class="cn.itcast.spring3.demo2.Bean2Factory" factory-method="getBean2"></bean>
实例工厂实例化 – 工厂方法模式
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
<!-- 第三种使用实例工厂实例化 -->
<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>
<bean id="bean3Factory" class="cn.itcast.spring3.demo2.Bean3Factory"/>
public class PersonServiceFactory {
public PersonService createPersonService(){
return new PersonServiceImpl();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
/** * Bean的实例化的测试 * * @author 姜涛 * */
public class SpringTest2 {
@Test
// 无参数的构造方法的实例化
public void demo1() {
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext(
"applicationContext.xml");
Bean1 bean1 = (Bean1) applicationContext.getBean(
"bean1");
System.out.println(bean1);
}
@Test
// 静态工厂实例化
public void demo2() {
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext(
"applicationContext.xml");
Bean2 bean2 = (Bean2) applicationContext.getBean(
"bean2");
System.out.println(bean2);
}
@Test
// 实例工厂实例化
public void demo3() {
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext(
"applicationContext.xml");
Bean3 bean3 = (Bean3) applicationContext.getBean(
"bean3");
System.out.println(bean3);
}
Bean的其余配置
Bean的命名 id属性和name属性
- 通常状况下,装配一个Bean时,经过指定一个id属性做为Bean的名称
- id 属性在IoC容器中必须是惟一的
- id 的命名要知足XML对ID属性命名规范
- id遵照XML约束的id的约束.id约束保证这个属性的值是惟一的,并且必须以字母开始,可使用字母、数字、连字符、下划线、句话、冒号
- 若是Bean的名称中含有特殊字符,就须要使用name属性
- 例如:
<bean name="#person" class="cn.itcast.bean.Person"/>
- 由于name属性能够相同,因此后出现Bean会覆盖以前出现的同名的Bean
类的做用范围
Bean的生命周期
- 配置Bean的初始化和销毁的方法:在xml文件中加入:
- init-method=”setup”
- destroy-method=”teardown”

- 执行销毁的时候,必须手动关闭工厂,并且只对scope=singleton有效
- 必须用子类执行 ClassPathXmlApplicationContext 中的close方法来实现。
Bean的生命周期的11个步骤
<bean id="customerService" class="cn.itcast.spring3.demo4.CustomerServiceImpl" init-method="setup" destroy-method="teardown">
<property name="name" value="itcast"></property>
</bean>
<bean class="cn.itcast.spring3.demo4.MyBeanPostProcessor"></bean>
//这里不须要写id,由于这是由Spring容器自动调用的。
- CustomerService & CustomerServiceImpl
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
public interface CustomerService {
public void add();
public void find();
}
public class CustomerServiceImpl implements CustomerService, BeanNameAware,ApplicationContextAware,InitializingBean,DisposableBean {
private String name;
public void setName(String name) {
System.out.println(
"第二步:属性的注入.");
this.name = name;
}
public CustomerServiceImpl() {
super();
System.out.println(
"第一步:实例化类.");
}
public void add(){
System.out.println(
"添加客户...");
}
public void find(){
System.out.println(
"查询客户...");
}
public void setBeanName(String name) {
System.out.println(
"第三步:注入配置的类的名称"+name);
}
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
System.out.println(
"第四步:注入applicationContext"+applicationContext);
}
public void afterPropertiesSet()
throws Exception {
System.out.println(
"第六步:属性设置后执行...");
}
public void setup(){
System.out.println(
"第七步:调用手动设置的初始化方法...");
}
public void destroy()
throws Exception {
System.out.println(
"第十步:调用销毁的方法...");
}
public void teardown(){
System.out.println(
"第十一步:调用手动销毁方法...");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
public class MyBeanPostProcessor implements BeanPostProcessor{
/** * bean:实例对象 * beanName:在配置文件中配置的类的标识. */
public Object
postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println(
"第五步:初始化以前执行...");
return bean;
}
public Object
postProcessAfterInitialization(
final Object bean, String beanName)
throws BeansException {
System.out.println(
"第八步:初始化后执行...");
// 动态代理:
if(beanName.equals(
"customerService")){
Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces() ,
new InvocationHandler() {
// 调用目标方法的时候,调用invoke方法.
public Object
invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(
"add".equals(method.getName())){
System.out.println(
"权限校验...");
Object result = method.invoke(bean, args);
//System.out.println(System.currentTimeMillis());
return result;
}
return method.invoke(bean, args);
}
});
return proxy;
}
return bean;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
public class SpringTest4 {
@Test
// Bean完整的生命周期
public void demo1() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
CustomerService customerService = (CustomerService) applicationContext.getBean(
"customerService");
customerService.add();
customerService.find();
applicationContext.close();
}
}
//结果以下:
第一步:实例化类
第二步:属性的注入
第三步:注入配置的类的名称 customerService
第四步:注入applicationContext org.springframework.context.support.ClassPathXmlApplicationContext@61baa894: startup date [Wed Jun
22 11:
49:
14 CST
2016]; root of context hierarchy
第五步:初始化以前执行
...
第六步:属性设置后执行
...
第七步:调用手动设置的初始化方法
...
第八步:初始化后执行
...
权限校验
...
添加客户
...
查询客户
...
11:
49:
14,
863 INFO ClassPathXmlApplicationContext:
1042 - Closing org.springframework.context.support.ClassPathXmlApplicationContext@61baa894: startup date [Wed Jun
22 11:
49:
14 CST
2016]; root of context hierarchy
11:
49:
14,
864 INFO DefaultListableBeanFactory:
444 - Destroying singletons
in org.springframework.beans.factory.support.DefaultListableBeanFactory@64bfbc86: defining beans [customerService,test.spring3.demo4.MyBeanPostProcessor
#0]; root of factory hierarchy
第十步:调用销毁的方法
...
第十一步:调用手动销毁的方法
...
IOC容器装配Bean
Bean中属性注入–基于XML方式
IoC容器装配Bean 基于XML配置方式
构造器注入
- 使用构造方法注入,在Spring配置文件中,经过
<constructor-arg>
设置注入的属性 (能够经过index或者type注入)
setter方法注入
- 使用setter方法注入,在Spring配置文件中,经过
<property>
设置注入的属性

<bean id="car2" class="cn.itcast.spring3.demo5.Car2">
<!-- <property>标签中name就是属性名称,value是普通属性的值,ref:引用其余的对象 -->
<property name="name" value="保时捷"/>
<property name="price" value="5000000"/>
</bean>
setter方法注入对象属性
<property>
标签中name就是属性名称,value是普通属性的值,ref:引用其余的对象

名称空间p:注入属性
Spring2.5版本引入了名称空间p
p:<属性名>="xxx"
引入常量值
p:<属性名>-ref="xxx"
引用其它Bean对象
引入名称空间:
xmlns:p="http://www.springframework.org/schema/p"

xml:
<bean
id=
"car2" class=
"cn.itcast.spring3.demo5.Car2" p:
name=
"宝马" p:price=
"400000"/>
<bean
id=
"person" class=
"cn.itcast.spring3.demo5.Person" p:
name=
"童童" p:car2-
ref=
"car2"/>
SpEL:属性的注入
- Spring3.0提供注入属性方式:
- 语法:
<bean id="" value="#{表达式}">
#{'神回复:哈哈'}
使用字符串
#{topicId3}
使用另外一个bean
#{topicId4.content.toUpperCase()}
使用指定名属性,并使用方法
#{T(java.lang.Math).PI}
使用静态字段或方法
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
<bean id="car2" class="cn.itcast.spring3.demo5.Car2">
<property name="name" value="#{'大众'}"></property>
<property name="price" value="#{'120000'}"></property>
</bean>
<bean id="person" class="cn.itcast.spring3.demo5.Person">
<!--<property name="name" value="#{personInfo.name}"/>-->
<property name="name" value="#{personInfo.showName()}"/>
<property name="car2" value="#{car2}"/>
</bean>
<bean id="personInfo" class="cn.itcast.spring3.demo5.PersonInfo">
<property name="name" value="张三"/>
</bean>
SpEL : 集合属性的注入 – List(数组)

SpEL : 集合类型属性注入 – Set

SpEL : 集合类型属性注入 – Map

SpEL :集合类型属性注入 – Properties

- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
<bean id="collectionBean" class="cn.itcast.spring3.demo6.CollectionBean">
<!-- 注入List集合 -->
<property name="list">
<list>
<value>童童
</value>
<value>小凤
</value>
</list>
</property>
<!-- 注入set集合 -->
<property name="set">
<set>
<value>杜宏
</value>
<value>如花
</value>
</set>
</property>
<!-- 注入map集合 -->
<property name="map">
<map>
<entry key="刚刚" value="111"/>
<entry key="娇娇" value="333"/>
</map>
</property>
<property name="properties">
<props>
<prop key="username">root
</prop>
<prop key="password">123
</prop>
</props>
</property>
</bean>
多配置文件的加载
第一种写法:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean1.xml",”bean2.xml”);
第二种方法:
<import resource="applicationContext2.xml"/>
Bean的属性注入–基于注解方式
IoC容器装配Bean , 基于注解配置方式
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- bean definitions here -->
</beans>
- 配置提示操做
- 将红框中地址复制到
Key
中

- 引入component-scan标签:
<context:component-scan base-package="cn.itcast.spring3"/>
,告诉Spring要去扫描哪些包下的类。

- Spring的框架中提供了与
@Component
注解等效的三个注解:
@Repository
用于对DAO实现类进行标注
@Service
用于对Service实现类进行标注
@Controller
用于对Controller实现类进行标注
- 三个注解是为了让标注类自己的用途清晰,Spring在后续版本会对其加强
自动装配 Bean
- 使用
@Autowired
进行自动注入
@Service
标注业务类
@Repository
标注DAO
@Autowired
默认按照类型进行注入
- 若是存在两个相同Bean类型,则按照名称注入
- @Autowired 注入时能够针对成员变量或者setter方法

- 经过@Autowired的required属性,设置必定要找到匹配的Bean,默认为true,为false时表示对异常不关心。
- 使用
@Qualifier
指定注入Bean的名称
- 使用
Qualifier
指定Bean名称后,注解Bean必须指定相同名称

普通属性
- @Value(value=”itcast”)
- private String info;
对象属性
- 按类型注入
- 按名称进行注入
- @Autowired 中有一个属性required,默认为true,为false时表示对异常不关心。
- @Qualifier(“userDao”) 按名称进行注入.
标准注解@Resource
@Autowired
@Qualifier(
"userDao")
private UserDao userDao;
@Resource(name=
"userDao")
private UserDao userDao;
Bean其余的属性的配置
- 配置Bean初始化方法和销毁方法:
- init-method 和 destroy-method.
@PostConstruct
: 初始化
@PreDestroy
: 销毁

配置Bean的做用范围
- 使用注解配置的Bean和
<bean>
配置的同样,默认做用范围都是singleton

Spring3.0能够 使用Java类提供Bean定义信息
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
@Configuration
public class BeanConfig {
@Bean(name=
"car")
public Car
showCar(){
Car car =
new Car();
car.setName(
"长安");
car.setPrice(
40000d);
return car;
}
@Bean(name=
"product")
public Product
initProduct(){
Product product =
new Product();
product.setName(
"空调");
product.setPrice(
3000d);
return product;
}
}
实际开发中使用XML仍是注解
- XML:
- 注解:
- 两种方式结合;通常使用XML注册Bean,使用注解进行属性的注入

Spring整合web开发
web.xml中的配置
- 将Spring容器初始化,交由web容器负责
- 配置核心监听器 ContextLoaderListener
- 配置全局参数contextConfigLocation
- 用于指定Spring的框架的配置文件位置(由于:applicationContext.xml文件与默认位置不一致)

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation
</param-name>
<param-value>classpath:applicationContext.xml
</param-value>
</context-param>
得到WebApplicationContext对象
- 由于Spring容器已经交由web容器初始化和管理,得到WebApplicationContext对象,须要依赖ServletContext对象 一般在Servlet中完成:
WebApplicationContext applicationContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext applicationContext = (WebApplicationContext) getServletContext()
.getAttribute(WebApplicationContext
.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)
;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name></display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation
</param-name>
<param-value>classpath:applicationContext.xml
</param-value>
</context-param>
<servlet>
<servlet-name>UserServlet
</servlet-name>
<servlet-class>cn.itcast.servlet.UserServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserServlet
</servlet-name>
<url-pattern>/userServlet
</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp
</welcome-file>
</welcome-file-list>
</web-app>
- UserServlet & UserService
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
public class UserServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "applicationContext.xml");*/
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
UserService userService = (UserService) applicationContext
.getBean(
"userService");
userService.sayHello();
}
public class UserService {
public void sayHello(){
System.out.println(
"Hello Spring web...");
}
}
Spring集成JUnit测试
- 1.程序中有Junit环境.
- 2.导入Spring test测试jar包
- spring-test-3.2.0.RELEASE.jar
- 3.测试代码:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations=
"classpath:applicationContext.xml")
public class SpringTest {
@Autowired
private UserService userService;
@Test
public void demo1(){
userService.sayHello();
}
}