Spring
简介:
Spring是一个开源的轻量级应用框架,其目的是用于简化企业级应用程序的开发,减少侵入.
.Spring提供了IOC和AOP应用,开发者将组件的耦合度将至最低,即解耦,便于系统日后的维护和升级.
.Spring为系统提供了一整体的解决方案,开发者可以利用它本身提供的功能外,也可以与第三方框架和
技术整合应用,可以自由选择采用哪种技术进行开发.
Spring框架可以完全接管MVC的全部功能.
为什么要用Spring框架
Spring的本质是管理软件中的对象,如何创建对象和维护对象之间的关系.
IOC和AOP
1.什么是IOC
Inversion of Control:控制反转(反转资源获取的方向)
DI(Dependency Injection)IOC的另一种表达方式,
即组件以一些预先定义好的方式,如setter方法接受来自
如容器的资源注入,相对于IOC而言,这种表达更直接.
配置Spring的xml文件
--练习:Spring的helloWorld
步骤一:导入Spring的相关jar包
Spring的最小环境(6个jar包)
commons-logging-1.1.1.jar
spring-aop-3.2.8.RELEASE.jar
spring-beans-3.2.8.RELEASE.jar
spring-context-3.2.8.RELEASE.jar
spring-core-3.2.8.RELEASE.jar
spring-expression-3.2.8.RELEASE.jar
步骤二:创建Spring的配置文件applicationContext.xml
通过插件提供的配置文件直接生成
步骤三:配置javaBean(符合java规范的普通java类)
步骤四:实例化IOC容器,完成资源(对象)的注入
ps:1
<property name="name" value="Spring"></property>
property标签中name属性所对应的值为JavaBean中对应的set方法.
2.在实例化IOC容器时,容器中配置的JavaBean也会一起被实例化.
Spring容器的详细简介:
.在Spring中,任何的java类和javaBean都被当成bean处理.
.什么是JavaBean:一种简单规范的java对象
.Spring容器实现了IOC和AOP机制,这些机制可以简化Bean对象创建和Bean对象之间的解耦.
.Spring容器有ApplicationContext和BeanFactory两种类型.
何时使用Spring?
当需要管理JavaBean对象时候就可以使用,Spring是最简洁的对象管理方案之一.
Spring容器的实例化
ApplicationContext继承自BeanFactory,拥有更多的企业级方法,推荐使用类型.
//加载文件系统中的配置文件实例化
ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\applicationContext.xml");
//加载工程classpath下的配置文件实例化.
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Spring容器的使用
.从本质上讲,BeanFactory和ApplicationContext仅仅只是一个维护bean定义以及依赖关系的高级工厂接口,
通过BeanFactory和ApplicationContext我们可以访问bean定义.
Bean的定义
<bean id="标示符" class="Bean类型">
通过getBean("标示符")方法获取
Bean的实例化.
.Spring容器创建Bean对象的方法有3种
-构造器来实现
<bean id="helloWorld" class="com.sicheng.javaBean.HelloWorld">
</bean>
<bean name="helloWorld" class="com.sicheng.javaBean.HelloWorld">
</bean>
id或name属性用于指定Bean名称,用于从spring中查找这个Bean对象
class用于指定Bean的类型,会自动调用无参构造器创建对象.
-使用静态工厂方法实例化
-使用实例工厂方法实例化
Bean的命名
.Bean的名称
-在Spring容器中,每个Bean都需要有名字(标示符),该名字可以用<bean>元素的id和name属性指定.
(唯一性,不能使用特殊符号如:"/"等)
.Bean的别名.
Bean的作用域
.Spring容器在实例化Bean时,可以创建以下作用域的Bean对象
作用域 描述
singleton 在每个Spring IOCring容器中一个Bean定义对应一个对象实例,默认项
prototype 一个bean定义对应多个对象实例
request
session
global Session
利用Spring容器创建JavaBean对象
步骤一:导包
步骤二:新建Spring配置文件
步骤三:配置javaBean
步骤四:测试
Bean的生命周期回调
.指定初始化回调方法init
.指定销毁回调方法destroy
ps:指定销毁回调方法,仅适用于singleton模式的bean
Bean延迟实例化
指定bean依赖关系
控制bean的实例化
测试bean的作用域,bean的生命周期回调(创建,初始化,被使用,销毁),bean对象的创建时机以及如何指定bean的依赖关系.
步骤一:新建ExampleBean.
bean的生命周期回调(创建,初始化,被使用,销毁)
销毁:希望bean对象销毁前自动调用destroy方法
在根元素或顶级元素<beans>中default-init-method属性以及
default-destroy-method属性,可以为容器中的所有<bean>指定初始化回调方法以及销毁回调方法
步骤三:bean对象的创建时机
ps:IOC容器中bean对象在容器被加载时就会被创建
原因:为了节省资源,当用户需要用到某些bean在创建指定的bean.
解决法案:
通过设置配置文件属性lazy-init="true",可以改变spring容器创建对象的时机
使用该属性之后,容器中对象不使用则不创建.
在顶级beans元素中使用default-lazy-init为容器中所有的bean指定延迟实例化特性
步骤四:指定bean依赖关系.
A B
A类中有一个B类的属性
A类中实例依赖于B类
A类型即使没有B类型的属性
但是如果A类型要创建对象成功必须先实例化B类型对象
<bean id="ExampleBean" depends-on="ExampleBean1"class="com.sicheng.javaBean.ExampleBean"></bean>
<bean id="ExampleBean1" class="com.sicheng.javaBean.ExampleBean1"></bean>
通过以上配置可以看出ExampleBean 依赖于ExampleBean1
因此在创建ExampleBean的同时也创建ExampleBean1
4.利用Spring实现bean属性setter方法注入.
JDBCDateSource类封装了管理数据连接的方法getConnection
先利用Spring实现JDBCDateSource对象的创建(实例化),在使用setter注入方式将数据库
连接参数注入给JDBCDateSource,这样就可以正常的调用getConnection方法获取数据库连接了.
IOC:控制反转
IOC:是指程序中对象获取的方式发生反转,由最初的new方式创建,转变为由第三方框架创建,注入.
第三方框架一般是通过配置方式指定注入哪一个具体实现,从而降低了对象之间的耦合度
.Spring容器是采用DI方式实现了IOC控制.IOC是Spring框架的基础和核心.
IOC是一种思想,而DI是实现IOC的主要技术途径.
DI主要有两种注入方式,即setter注入,和构造器注入
setter注入:略
构造器注入
基于构造器的注入是通过调用参数的构造器来实现的,容器在bean被实例化的时候,根据参数类型执行相应的构造器.
练习:利用构造器参数实现依赖属性的注入.
1.创建一个Dao层实现类.
2.配置该类和JDBCDateSource的依赖关系
3.使用构造器注入的方式将JDBCDateSource的实例注入到Dao层类中.
自动装配
Spring Ioc容器可以自动装配(autowire)相互协作bean之间的关联关系
,autowire可以针对单个bean进行设置,autowire的方便之处在于减少xml的注入配置.
如何自动装配
在xml配置文件中,可以在<bean/>元素中使用autowire属性指定自动装配规则,自动装配一个有五种
属性值 描述
no 禁用自动装配,默认值.
byName 根据属性名自动装配,此选项将检查容器并根据名字查找属性名完全一致的bean,并将其与属性自动装配
byType 如果容器中存在一个与指定属性类型相同的bean,那么与该属性自动装配
constuctor 与byType的方式类似,不同之处在于他应用于构造器参数
autodetect 略
--练习:
创建一个service层,然后将Dao层实例注入到service中.
<bean id="userService" class="com.sicheng.service.UserService" autowire="byType">
通过上述配置,spring会自动的根据类型调用setter方法完成UserService依赖的对象userDao的注入,不必进行完整的配置.
问题: 当符合该类型的对象有多个时,是否可以使用当前配置.---不能
Spring基础结束.
自动扫描注解标记(重点)
Spring IOC容器
参数值注入.
1.注入基本值
<value/>元素可以通过字符串指定属性或构造器参数的值.
容器将字符串从java.lang.String类型转换为实际的属性或参数类型后给Bean对象注入.
<property name="pwd" value="orcl"></property>
或
<property name="pwd">
<value>orcl<value/>
</property>
2.注入bean对象
注入外部bean(引用方式,方便重用)
<bean id="userDao" class="com.sicheng.dao.OracleUserDao">
<!-- 利用构造器参数注入bean属性 -->
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
注入内部bean
<bean id="userService" class="com.sicheng.service.UserService">
//通过内部bean的方式注入
<property name="userDao">
<bean class="com.sicheng.dao.OracleUserDao"></bean>
</property>
</bean>
注入集合
通过<list/>,<set/>,<map/>及<props/>元素可以定义和设置与java类型中对应
的List,Set,Map以及Properties的属性值
练习:
给MessageBean注入参数值.
通过MessageBean类演示Spring的多种类型的数据的注入方式.
1.注入基本值
2.注入Bean对象
3.直接集合注入
4.引用方式集合注入
5.注入Spring表达式
Spring引入了一种表达式语言,这和统一的EL在语法上很相似,这种表达式语言可以用于定义基于XML和注解配置的Bean.
注入一个Properties文件信息.
<!-- 加载db.properties文件 -->
<util:properties id="jdbcProperties" location="classpath:db.properties"></util:properties>
<property name="driver" value="#{jdbcProperties.driver}"></property>
6.注入null或空字符串
<property name="driver"><null></property>
测试引用方式集合注入
采用引用方式注入集合对象
基于注解的组件扫描.
Spring IOC容器
什么是组件扫描
.指定一个包路径,Spring会自动扫描该包及其子包所有的组件类.当发现组件类定义前有特定的注解标记时,
就会将该组件纳入到Spring容器中,等价于原有的XML配置文件中的<bean>定义功能.
指定扫描类路径.
<context:component-scan base-package="com.sicheng.bean"></context:component-scan>
指定扫描类路径后,并不是该路径下所有组件类都扫描到Spring容器中,只有组件类定义前面有以下注解标记时,
才会扫描到Spring容器中.
@Compoent 通用注解
@Name 通用注解
@Repository 持久化层组件注解(Dao)
@Service 业务层组件注解
@Controller 控制层组件注解
练习:通过组件扫描以及注解的方式获取指定的bean.
自动扫描组件的命名
当一个组件在扫描过程中被检测到时,会生成一个默认ID值,默认id为小写开头的类名.
也可以在注解标记中自定义id值.
比如:@Component("example")
指定组件的作用域
通常受Spring管理的组件,默认的作用域是"singleton"
如果需要其他的作用域可以使用注解@Scope注解,只要在注解中提供作用域名称即可
比如:@Scope("prototype")
初始化和销毁回调的控制
使用@PostConstruct和@PreDestroy注解分别用于指定初始化和销毁回调方法.
@PostConstruct
public void init(){
System.out.println("初始化ExampleBean");
}
@PreDestroy
public void destroy(){
System.out.println("销毁ExampleBean");
}
指定依赖注入关系.
具有依赖关系的Bean对象,利用下面任意一种注解都可以实现关系注入.
@Resource
@Autowried/@Qualifier
@Inject/@Name
@Resource注解标记可以用在字段定义或setter方法定义前面.
默认是先按名称匹配注入,然后按类型匹配注入.
练习:
使用注解的方式重构UserService,JDBCDdataSource.
@Value:为基本属性注入值.
ps:建议使用名称匹配,因为当遇到多个匹配Bean时注入会发生错误,所以建议
以如下形式使用@Resource注解
显示指定名称@Resource(name="userDao")
@Autowried:注解标记也可以用在字段定义和setter方法定义前面.默认按类型匹配.
用法同@Resource.
@Autowried当遇到很多个匹配Bean注入会发生错误
解决方案:
@Resource(name="userDao")
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
等同于:
@Autowried
@Qualifier("userDao")
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
----------------------------------------
@Autowried
@Qualifier("userDao")
private UserDao userDao;
----------------------------------------
@Autowried
public void setUserDao(@Qualifier("userDao") UserDao userDao) {
this.userDao = userDao;
}
@Inject/@Name 用法等同于 @Autowried/@Qualifier
ps:使用该注解 需要 JSR-330的jar包,该注解是Spring3.0后开始增添的对JSR-330的支持.
SSH
spring+hibernate
1.1整合步骤:导包
-导入hibernate开发包
-导入Spring开发包
-导入数据库驱动包
ps:如果包重复,则保留高版本,去掉低版本.
1.2配置applicationContext.xml
.按照如下步骤配置
struts2+spring
struts2+spring+hibernate
----------------------------------------------------------------------------------------
bean.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"
default-destroy-method="destroy" default-init-method="init"
default-lazy-init="true"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
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-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
<context:component-scan base-package="com.sicheng"></context:component-scan>
<bean id="ExampleBean" depends-on="ExampleBean1"
class="com.sicheng.javaBean.ExampleBean"></bean>
<bean id="ExampleBean1"
class="com.sicheng.javaBean.ExampleBean1"></bean>
<!-- 加载db.properties文件 -->
<util:properties id="jdbcProperties" location="classpath:db.properties"></util:properties>
<!-- setter注入
<bean id="dataSource" class="com.sicheng.javaBean.JDBCDdataSource">
<property name="driver" value="#{jdbcProperties.driver}"></property>
<property name="url" value="#{jdbcProperties.url}"></property>
<property name="user" value="#{jdbcProperties.user}"></property>
<property name="pwd" value="#{jdbcProperties.pwd}"></property>
</bean>
-->
<!-- 构造器注入
<bean id="userDao" class="com.sicheng.dao.OracleUserDao">
利用构造器参数注入bean属性
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
-->
<!-- userService
<bean id="userService" class="com.sicheng.service.UserService" autowire="byType">
</bean>
-->
</beans>
-----------------------------------------------------------------------------------
applicationContext.xml
<!--
<bean id="helloWorld" scope="singleton" class="com.sicheng.javaBean.HelloWorld">
<property name="name" value="Spring"></property>
</bean> -->
<!-- 1.用构造器来实例化 -->
<bean id="calendarObj01" class="java.util.GregorianCalendar"></bean>
<!-- 2.用静态工厂方法来实例化 -->
<bean id="calendarObj02" class="java.util.Calendar" factory-method="getInstance"></bean>
<!-- 3.用实例工厂方法来实例化 -->
<bean id="calendarObj03" class="java.util.GregorianCalendar"></bean>
<bean id="dateobj" factory-bean="calendarObj03" factory-method="getTime"></bean>
<!-- 这里定义了两个bean,其中一个bean calendarObj03是用于创建dateobj对象的实例工厂 -->
</beans>
-----------------------------------------------------------------------------------------------
application.xml
<bean id="messageBean" class="com.sicheng.text.MessageBean">
<property name="username" value="tom"></property>
<property name="age" value="12"></property>
<property name="someList" ref="oneList"></property>
</bean>
<!-- 采用引用方式注入集合对象 -->
<util:list id="oneList">
<value>北京Tom</value>
<value>上海</value>
<value>广州</value>
</util:list>
<!--
<property name="someList">
<list>
<value>北京</value>
<value>上海</value>
<value>广州</value>
</list>
</property>
<property name="someSet">
<set>
<value>周杰伦</value>
<value>刘德华</value>
<value>阿萨德</value>
</set>
</property>
<property name="someMap">
<map>
<entry key="1001" value="java"></entry>
<entry key="1002" value="javaweb"></entry>
<entry key="1003" value="php"></entry>
</map>
</property>
<property name="someProps">
<props>
<prop key="username">root</prop>
<prop key="password">1231</prop>
<prop key="phone">123345</prop>
</props>
</property>-->