推荐教程
Spring介绍
Spring 是一个开源框架,是一个分层的 JavaEE 一站式框架。
所谓一站式框架是指 Spring 有 JavaEE 开发的每一层解决方案。
-
WEB层:SpringMVC
-
Service层:Spring的Bean管理,声明式事务
-
DAO层:Spring的JDBC模板,ORM模板
优点:
-
IOC:方便解耦合
-
AOP:对程序进行扩展
-
轻量级框架
-
方便与其他框架整合
Spring使用
Spring开发包解压后的目录介绍:
-
docs: Spring 开发规范和API
-
libs: Spring jar 包和源代码
-
schema: Spring 配置文件的约束
DataAccess 用于数据访问,WEB 用于页面显示,核心容器也就是IOC部分。
控制反转(IOC)
控制反转(Inversion of Control)是指将对象的创建权反转(交给)Spring。
使用IOC就需要导入IOC相关的包,也就是上图中核心容器中的几个包:beans,context,core,expression四个包。
实现原理
传统方式创建对象:
UserDAO userDAO=new UserDAO();
进一步面向接口编程,可以多态:
UserDAO userDAO=new UserDAOImpl();
这种方式的缺点是接口和实现类高耦合,切换底层实现类时,需要修改源代码。程序设计应该满足OCP元祖,在尽量不修改程序源代码的基础上对程序进行扩展。此时,可以使用工厂模式:
class BeanFactory{
public static UserDAO getUserDAO(){
return new UserDAOImpl();
}
}
此种方式虽然在接口和实现类之间没有耦合,但是接口和工厂之间存在耦合。
使用工厂+反射+配置文件的方式,实现解耦,这也是 Spring 框架 IOC 的底层实现。
//xml配置文件
//<bean id="userDAO" class="xxx.UserDAOImpl"></bean>
class BeanFactory{
public static Object getBean(String id){
//解析XML
//反射
Class clazz=Class.forName();
return clazz.newInstance();
}
}
IOC XML 开发
在 docs 文件中包含了 xsd-configuration.hmtl 文件。其中定义了 beans schema。
<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
<bean id="userService" class="x.y.UserServiceImpl">
</bean>
</beans>
调用类:
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService)applicationContext.getBean("userService");
userService.save();
IOC 和 DI
DI 指依赖注入,其前提是必须有 IOC 的环境,Spring 管理这个类的时候将类的依赖的属性注入进来。
例如,在UserServiceImpl.java中:
public class UserServiceImpl implements UserService{
private String name;
public void setName(String name){
this.name=name;
}
public void save(){
System.out.println("save "+name);
}
}
在配置文件中:
<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 id="userService" class="spring.demo1.UserServiceImpl">
<!--配置依赖的属性-->
<property name="name" value="tony"/>
</bean>
</beans>
测试代码:
@Test
public void demo2(){
//创建Spring工厂
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService)applicationContext.getBean("userService");
userService.save();
}
运行结果:
save tony
可以看到,在配置文件中配置的属性,在 Spring 管理该类的时候将其依赖的属性成功进行了设置。如果不使用依赖注入,则无法使用接口,只能使用实现类来进行设置,因为接口中没有该属性。
Spring 的工厂类
-
BeanFactory: 老版本的工厂类,在调用
getBean()
方法时,才会生成类的实例。 -
ApplicationContext: 在加载配置文件的时候,就会将 Spring 管理的类都实例化。有两个实现类:
<ol><li> <p>ClassPathXmlApplicationContext: 加载类路径下的配置文件</p> </li> <li> <p>FileSystemXmlApplicationContext: 加载磁盘下的配置文件</p> </li> </ol></li>
bean标签配置
-
id: 唯一约束,不能出现特殊字符
-
name: 理论上可以重复,但是开发中最好不要。可以出现特殊字符
生命周期:
-
init-method: bean被初始化的时候执行的方法
-
destroy-method: bean被销毁的时候执行的方法
作用范围:
-
scope: bean的作用范围,有如下几种,常用的是前两种
<ul><li> <p>singleton: 默认使用单例模式创建</p> </li> <li> <p>prototype: 多例</p> </li> <li> <p>request: 在web项目中,spring 创建类后,将其存入到 request 范围中</p> </li> <li> <p>session: 在web项目中,spring 创建类后,将其存入到 session 范围中</p> </li> <li> <p>globalsession: 在web项目中,必须用在 porlet 环境</p> </li> </ul></li>
属性注入设置
-
构造方法方式的属性注入: Car 类在构造方法中有两个属性,分别为 name 和 price。
<bean id="car" class="demo.Car">
<constructor-arg name="name" value="bmw">
<constructor-arg name="price" value="123">
</bean>
-
set 方法属性注入: Employee 类在有两个 set 方法,分别设置普通类型的 name 和引用类型的 Car (使用 ref 指向引用类型的 id 或 name)。
<bean id="employee" class="demo.Employee">
<property name="name" value="xiaoming">
<property name="car" ref="car">
</bean>
-
P名称空间的属性注入: 首先需要引入p名称空间:
<beans xmlns="http://www.springframework.org/schema/beans"
//引入p名称空间
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">
</beans>
如果是普通属性:
<bean id="car" class="demo.Car" p:name="bmv" p:price="123">
</bean>
如果是引用类型:
<bean id="employee" class="demo.Employee" p:name="xiaoming" p:car-ref:"car">
</bean>
-
SpEL(Spring Expression Language)属性注入(Spring 3.x以上版本)
<bean id="car" class="demo.Car">
<property name="name" value="#{'xiaoming'}">
<property name="car" ref="#{car}">
</bean>
-
集合类型属性注入:
<bean id="car" class="demo.Car">
<property name="namelist">
<list>
<value>qirui</value>
<value>baoma</valu