一)spring概述
(1)回顾已学框架所在的层次,能创建何种应用与常见解决方案:
struts2:位于web层/表示层/表现层,创建web应用,常见解决方案:上传,下载,验证。。。hibernate:位于持久层/访问层,创建web/javase应用,常见解决方案:连接不同的数据库,简化CURD操作,关联操作
spring:位于任意层,创建web/javase应用,常见解决方案:创建bean,装配bean,设置bean的关系。。。
(2)什么是spring
目标:简化JavaEE的开发,尽量做到少侵入性程序员代码
(A)全方位:理论上spring框架可以用上任意层中,但经过时间经验,spring还是集中运用到业务层,
并没有与struts2和hibernate抢其它二层
(B)轻量级:
(A)spring无需过多资源,例如:无需导入过多jar包
(B)spring框架并没有过多干涉程序员的习惯,例如:就一个普通的JavaBean对象,spring框架能够注入对应的值
无需实现特定的接口或继承特定的类
(C)spring框架共有6个模块,需要哪个模块就将该框架导入到你的工程中去,不需要就去掉,非常灵活
(C)常见解决方案:
(A)创建JavaBean
(B)设置JavaBean内置的值(基本类型和引用类型)
(C)设置JavaBean之间的关系
(D)声明式事务处理
(E)定时器,远程调用
(D)与其它层框架共存:
(A)能够与struts2等表示层框架整合
(B)能够与hibernate等持久层框架整合
注意:所谓整合,就是spring框架,有对应的功能,将struts2和hibernate包括进来,
底层还是按照struts2和hibernate的流程工作。
(4)为什么要使用spring
只要位于spring容器中的通过POJO对象,就能拥有:创建/注入值/依赖/事务/定时器。。。
无需手工编码,但只需配置在spring.xml文件中即可
但如果你是通过手工new 出来的对象,就没有上述功能了
(5)使用spring的好处
IOC:
原来:Boy需要自动找Girl,类似于new Girl(),叫正向控制
现来:Boy无需要自动找Girl,不需要new Girl(),这一切交给spring框架,
spring框架会根据Boy的需求,创建对应的Girl后,传入到Boy类中,
所以Boy类需要提供接收方法,叫反向控制
DI:
Boy需要Girl属性,通过setter方法,让spring框架传入girl的对象,
上述过程叫做依赖注入。
二)spring工作过程祥解
(1)所需jar包:
spring.jar:它已经包括六大模块所需的所有jar包,如果项目中,你知道某些模块,可以选用不同的jar即可
commons-logging.jar:spring框架内部使用第三方开源日志功能
(2)XML配置文件
采用schema来约束的,不是dtd
XML文件的位置任意,但提倡写在IDE工具的src/spring.xml
因为,尽量做到java代码少变动或不变动
XML的声明:
\spring-framework-2.5.6\samples\petclinic\war\WEB-INF\applicationContext-hibernate.xml
相当于spring框架的核心配置,相当重要
(3)什么是bean
它是spring框架的叫法,表示spring.xml文件中,每个<bean/>标签
将来<bean/>标签,会被spring框架创建,形成一个对象
(4)启动spring框架/spring容器/ioc容器的二种方式及特点
(A)ClassPathXmlApplicationContext(new String[]{...})【提倡】
ApplicationContext是一个接口,表示spring容器/ioc容器
ClassPathXmlApplicationContext是一个实现类之一,只能从类路径中读取spring.xml文件
所谓类路径:就是IDE工具的src目录下,但不包括src目录
可加载一个或多个spring.xml文件
(B)FileSystemXmlApplicationContext(new String[]{...})
FileSystemXmlApplicationContext是一个实现类之一,只能从文件路径中读取spring.xml文件
所谓文件路径:就是IDE工具的工程目录下,但不包括工程名目录,即 src/cn/itcast/javaee/spring/ioc/type1/spring.xml
(5)启动spring容器/ioc容器的内幕
(1)实例化ClassPathXmlApplication类
(2)读取指定目录下的spring.xml文件,在内存中形成一个JavaBean对象,该JavaBean对象看作是一个spring容器,
该容器中的每一个对象的id必须唯一,就算加载N个spring.xml文件,也必须保证所有的<bean id/>属性唯一。
一个spring.xml文件对应一个容器,这是不对的,只有一个spring容器
(3)在容器创建后,那么容器中的所有bean在默认情况下,都被创建了,类似new了
(4)在容器创建后,那么容器中的所有bean的属性值,都注入了
注意:如果上述启动失败,控制台有提示
(6)在spring容器/ioc容器中判断是否有对应的bean
ac.containsBean("bOyID");
true表示spring容器/ioc容器中已存在bean
false表示spring容器/ioc容器中不存在bean
(7)从spring容器/ioc容器中得到bean
Object obj = ActionContext.getBean("xxxID");
(8)spring开发步骤
(1)启动spring容器
(2)判断spring容器中是否有你需要的对象
(3)从spring容器中获取你所需要对象
(4)操作对象的业务方法
三)操作bean【IUserDao 和UserDao】
(1)实例化bean的三种方式
(A)通过无参构造器创建对象【提倡】
(B)没有无参构造器,通过静态工厂方法创建对象
(C)没有无参构造器,没有静态工厂方法,通过普通工厂方法创建对象
(2)指定bean的初始化方法和销毁方法,使用AbstractApplicationContext类来监听
(A)初始化init-method
(B)销毁destroy-method
注意:同一个类的多个对象,spring容器只会调用一次。
当有多个bean配置在spring.xml文件中,先配置的先执行init-method所指定的方法,
destory-method与init-method顺序相反。
下面来写一个入门案例:
(1)创建一个web应用或非web应用
(2)导入spring框架核心包:spring.jar和commons-logging.jar
(3)创建Girl.java类
(4)在任意目录下,创建spring.xml文件
目的:通知spring框架,创建bean,装配bean,设置bean间的关系
技术:xml
位置:任意
bean是spring中的叫法,它表示在spring.xml文件中配置的每个<bean/>标签
即表示某个类的对象
(5)写一个测试类
第一步写个实体类Boy:
package example.type1;
public class Boy {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
第二步写spring的配置文件applicationContext.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean id="boy" class="example.type1.Boy">
<property name="id" value="1001"></property>
<property name="name" value="小明"></property>
</bean>
</beans>
最后写个测试类:
package example.type1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
//启动spring容器,也就是加载applicationContext.xml
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(new String[]{"example/type1/applicationContext.xml"});
Boy boy= (Boy) applicationContext.getBean("boy");
System.out.println(boy.getId()+","+boy.getName());
}
}
下面用例子来介绍创建bean的三种方式。
第一种是通过无参构造器构造,这个是默认和提倡的:
第一步写接口(IUserDao)和实现类(UserDao)来举例:
IUserDao:
package example.type1;
public interface IUserDao {
public void addUser();
}
UserDao:
package example.type1;
public class UserDao implements IUserDao{
public UserDao(){
System.out.println("调用UserDao空参构造器");
}
public void addUser() {
System.out.println("增加用户");
}
}
写配置文件:
<?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-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean id="boy" class="example.type1.Boy">
<property name="id" value="1001"></property>
<property name="name" value="小明"></property>
</bean>
<!-- 配置实现类 -->
<bean id="userDao" class="example.type1.UserDao"></bean>
</beans>
测试类:
package example.type1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
//启动spring容器,也就是加载applicationContext.xml
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(new String[]{"example/type1/applicationContext.xml"});
//Boy boy= (Boy) applicationContext.getBean("boy");
//System.out.println(boy.getId()+","+boy.getName());
IUserDao userDao= (IUserDao) applicationContext.getBean("userDao");
userDao.addUser();
}
}
第二种创建bean的方式:没有无参构造器,通过静态工厂方法创建对象。
IUserDao不变,UserDao去掉空参构造器。
再写一个工厂类DaoFactory:
package example.type1;
public class DaoFactory {
public DaoFactory(){
System.out.println("实例化工厂");
}
public static IUserDao getUserDao(){
System.out.println("通过工厂的静态方法获取bean");
return new UserDao();
}
}
测试类和上面一样。
第三种创建bean的方式:没有无参构造器,没有静态工厂方法,通过普通工厂方法创建对象。
IUserDao不变,UserDao去掉空参构造器。
UserDao如下:
package example.type1;
public class UserDao implements IUserDao{
public UserDao(String str){
System.out.println("调用UserDao非空参构造器");
}
public void addUser() {
System.out.println("增加用户");
}
}
spring的配置文件applicationContext..xml:
<!-- 配置DaoFactory -->
<bean id="daoFactory" class="example.type1.DaoFactory">
</bean>
<!-- 配置UserDao -->
<bean id="userDao" factory-bean="daoFactory" factory-method="getUserDaoByNoStatic">
</bean>
DaoFactory的工厂类:
package example.type1;
public class DaoFactory {
public DaoFactory(){
System.out.println("实例化工厂");
}
public static IUserDao getUserDao(){
System.out.println("通过工厂的静态方法获取bean");
return new UserDao(null);
}
/*
* 获取UserDao对象,该方法是非静态的
*/
public IUserDao getUserDaoByNoStatic(){
System.out.println("通过工厂非静态方法获取对象");
return new UserDao(null);
}
}
测试类第一种的一样