Spring框架 第一天 IoC控制反转
课程安排(三天):
第一天: spring快速入门 IoC控制反转相关配置 (XML、注解)、web集成、junit集成
第二天: spring AOP 面向切面编程 (高级)、 JdbcTemplate的使用
第三天: spring声明式事务管理(基于AOP)、SSH整合 (XML和注解)
今天内容安排:
1、 spring概述 (作用、优点 )
2、 spring快速入门(IoC) ----------- IoC和DI的思想和概念
3、 spring IoC容器XML配置
4、 spring IoC容器注解配置
5、 web集成
6、 junit集成
1. Spring框架快速入门
1.1. Spring概述
1.1.1. 什么是spring ?
Spring是分层的JavaSE/EE full-stack(一站式) 轻量级开源框架
1) 分层 :JavaEE服务器三层结构 (表现层、 业务层、 持久层【集成层】)
2) 一站式:spring内部提供三层分别的解决方案
struts2 表现层框架
hibernate 持久层框架
spring (springMVC 表现层、 springIoC AOP 事务管理 业务层、 整合常用ORM框架 提供JdbcTemplate 持久层 )
3) 轻量级: 快速开发 ,相对于复杂强大EJB而言
1.1.2. spring核心
IoC (反转控制)和 AOP (面向切面编程)
1.1.3. spring由来
Spring 出现取代EJB框架,解决实际开发中一些问题 !
google 推出 guice (IOC框架 )
1.1.4. spring优点
1.1.5. spring体系结构
1.2. Spring IoC 快速入门案例
第一步: 去官方下载spring 框架,分析目录结构
官网地址:http://spring.io/
下载 springframework : http://www.springsource.org/download/community
最新版本: 4.2.x
课程学习: 3.2.x
spring 3.2.0 dist spring开发包
spring 3.0.2 dependemcies 依赖包 (包含常用开源框架的jar包 )
spring的jar包结构
分别提供 jar开发包、 javadoc文档包、 source源码包
第二步: 导入jar包
在src建立log4j.properties 日志配置文件
第三步: 理解IoC和DI
默认用户登陆功能 (业务层、 数据层 )
1) 编写传统登陆代码
2) 分析上面代码的问题 --- 紧密耦合
IoC (反转控制 ): 底层思想为了解除耦合 (工厂、反射、 配置文件 )
控制反转,将代码中自己创建对象权限,交给spring容器(工厂)
3) 在src提供 applicationContext.xml (习惯上)
头信息引入来自 xsd-config.html
<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">
4) 修改UserServiceImpl 代码
1.3. Spring DI的概念
面试提: IoC 和 DI的区别
什么是DI ? Dependecies injection 依赖注入
IoC和DI 描述的是同一件事 , DI 就是IoC别名
依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件
IoC 反转控制实现解除耦合
DI 是IoC 另一种描述
1、修改UserServiceImpl 提供 注入DAO的方法
2、在applicationContext.xml 完成DAO 自动注入到Service
在工厂提供Service对象同时,Service中自动注入DAO对象,可以直接使用
3、 测试代码 ,从工厂获取Service
1.4. 获取ApplicationContext对象两种方式
这是一种策略模式
ClassPathXmlApplicationContext 主要加载src/applicationContext,xml
FileSystemXmlApplicationContext 主要加载 WEB-INF/applicationContext.xml
1.5. 区分BeanFactory和ApplicationContext
Spring框架最顶层接口 BeanFactory (Bean工厂 ) ---- Spring容器就是一个工厂
ApplicationContext 是 BeanFactory 一个子接口
在实际开发中,基本上不用BeanFatory, 主要使用ApplicationContext , 因为功能更强大
l 国际化
l 自动装配
l 事件机制
ApplicationContext 默认在工厂创建时,对所有单例Bean进行初始化
BeanFactory 默认在getBean时,才会对Bean初始化
1.6. 配置schema提示功能
2. Spring IoC容器装配Bean(XML方式)
2.1. IoC容器实例化Bean三种方式
2.2.
第一种: 默认无参数构造器
第二种: 静态工厂方法
第三种: 实例工厂方法
加一种: FactoryBean
面试题: BeanFactory和FactoryBean的区别 ?
BeanFactory 指整个spring容器,可以管理各种对象,从工厂获取各种对象
FactoryBean 可以获取一种对象的工厂
FactoryBean 可以通过实现 getObject() 实现返回对象 !
配置
Spring容器发现配置Bean class是FactoryBean 自动调用getObject方法返回 !
2.3. Bean的几种作用域
配置<bean>元素 scope属性的
singleton 单例, 在整个spring IoC 容器只存在唯一对象
prototype 多例, 每次进行getBean 创建新的对象
request ,创建Bean, 放入request范围 request.setAttribute
session ,创建Bean ,放入session范围 session.setAttribute
globalSession 全局会话, 分布式多个系统, 共享同一个会话 (了解 )
配置applicationContext.xml
单例Bean,在ApplicationContext对象 (容器对象) 初始化时进行创建
多例Bean,在getBean时创建返回
2.4. Bean的生命周期
2.4.1. 初始化和销毁方法的设置
在<bean> 可以配置两个属性:
init-method 指定初始化的方法、 destroy-method 指定销毁方法
配置
问题: 默认代码不会执行销毁的
因为程序不知道销毁的时机 , 销毁必须收到调用容器的close
2.4.2. 重点:Bean的后处理器 (底层)
BeanPostProcessor 接口
Factory hook that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies 。
对lifeCycleBean 进行代理, 对print方法打印运行时间!
2.5. Bean属性依赖注入
2.5.1. 依赖注入三种方式
什么叫依赖注入?
由容器,自动为目标对象注入依赖的属性
Spring 支持构造器参数注入 和setter方法属性注入 ,不支持接口注入
2.5.2. 构造函数参数注入
构造方法参数 对应 配置文件 <constructor-arg> 元素
可以index|name|type 三选一 、三选二 ; ref|value 二选一
2.5.3. setter方法注入(开发推荐)
为需要注入属性提供setter方法
配置 每个注入属性, 对应<property> 元素
2.5.4. p名称空间的使用
spring2.5以后,为了简化setter方法属性注入,引用p名称空间的概念
可以将<property> 子元素,简化为<bean>元素属性配置 !!
1、 在applicationContext.xml 引入p 名称空间
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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">
2、 简化注入的配置
2.5.5. spEL表达式语言
spring3.0 以后 提供 spEL (spring expression language)表达式语言
在spring配置文件中通过 #{} 引用另一个Bean,引用属性、调用方法
#{beanId} 引用另一个对象
#{beanId.属性名} 引用另一个对象的属性
#{beanId.方法()} 调用另一个对象的方法
2.5.6. 集合类型的属性注入(了解)
Spring 对每个常用集合对象,提供单独元素完成注入
List 对象 ---- <list> 元素
Set 对象 ---- <set> 元素
Map对象 ----<map>元素
Properties 对象 ---- <props> 元素
通过配置,注入集合类型元素
集合属性的注入,主要用于框架的配置 !
3. Spring IoC容器装配Bean(注解方式)
3.1. 使用注解完成Bean的注册
XML方式: <bean id="" class="" />
第一步: 创建新的项目spring3_day1_annotation ,导入jar包
Spring开发 xml配置和注解配置 导入的jar包是一样的!!
src下提供log4j.properties 和 applicationContext.xml
第二步: 编写业务类
spring2.5 以后提供@Component注解,进行bean的注册
第三步: 配置applicationContext.xml 注解Bean的扫描 (包扫描机制)
引入context 名称空间
<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>
实际开发中,通常使用是@Component 的三个等价的注解
3.2. 注解完成Bean属性的依赖注入
注解注入,可以在setter方法上注入,也可以直接在属性成员上注入!
3.2.1. 简单类型数据注入
spring3.0 提供 @Value 注解,可以注入简单数据类型
3.2.2. 复杂对象类型数据注入
第一种: 使用@Value注解 结合 spEL表达式 (spring3.0)
第二种: 使用@Autowired 结合 @Qualifier 注解 (Spring 2.0 )
按类型注入
按名称注入
第三种: 使用@Resouce注解 (JSR-250标准 )
第四种: 使用 @Inject 注解 (JSR-330标准 )
导入 javax.inject-1.jar
按照类型注入
按照名称注入
3.3. 其它相关注解配置
3.3.1. 初始化和销毁的注解
XML 配置<bean> 指定init-method 和 destroy-method
注解 @PostConstruct 相当于 init-method , @PreDestroy 相当于 destroy-method
执行销毁方法,必须手动close容器
3.3.2. Bean的作用域
通过添加@Scope注解,指定Bean的作用域 ---- 默认singleton 单例
省略 value=
3.3.3. XML和注解混合配置
Spring2.0年代: 所有Bean定义采用XML, Bean关系注入采用注解
XML 配置注册Bean,激活注解的注入 (@Autowired)
添加 <context:annotation-config>
注意: <context:componet-scan> 包括 <context:annotation-config> 功能
4. Spring框架与web项目集成
直接使用今天讲解内容,在web中使用spring,发现问题 !
1、 新建web项目 spring3_day1_web 导入jar和配置文件
2、 编写HelloServlet 、HelloService (交给Spring管理 )
配置applicationContext.xml
Servlet代码
3、 发现问题,每次访问Servlet都会创建新的Spring容器对象
一个项目中 spring容器只需要一个就可以了 !如何只有一个!
web项目中:确保对象唯一, 放入ServletContext 范围 !
项目启动时,放入spring容器对象 ------ ServletContextListener 对象
4、Spring框架内容为我们提供了这样的Listener ,位于spring-web开发包 !
导入 spring-web-3.2.0.RELEASE.jar
配置Listener 在web.xml
错误:Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
默认会去WEB-INF找配置文件
配置文件位置
这里classpath: 必须小写,相当于WEB-INF/classes
5、Servlet 从ServletContext 范围获取对象
写法一:
写法二:
5. Spring框架与junit集成
第一步: 导入spring-test jar包
项目导入junit
第二步: 通过注解初始化容器
new ClassPathXmlApplicationContext 简化
第三步: 注入Bean测试
测试集成中不需要配置 <context:annotation-config> !!!可以直接@Autowired
作业:
登陆代码练习 (新建项目、使用仓库系统 ) --- struts2 + spring +hibernate
思路: 在struts2 Action代码里使用
WebApplicationContextUtils.getWebApplicationContext(ServletContext) ;
applicationContext.getBean("service")
DAO 依赖注入到service ,Service 直接调用DAO