7 -- Spring的基本用法 -- 1...2
7.1 Spring简介和Spring4.0的变化
7.1.1 Spring 简介
当使用Spring框架时,必须使用Spring Core Container(即Spring容器),它代表了Spring框架的核心机制,Spring Core Container主要由 org.springframework.core、org.springframework.beans、org.springframework.context、org.springframework.expression四个包及其子包组成,主要提供Spring IoC容器支持。
7.1.2 Spring 4.0 的变化
7.2 Spring 入门
7.2.1 Spring 下载和安装
1.下载spring-framework-4.x.x.RELEASE-dist.zip
docs : 存放Spring的相关文档,包含开发指南、API参考文档。
libs : 该目录下的JAR包分为三类--1Spring框架class文件的JAR包;2Spring框架源文件的压缩包,文件名以-sources结尾;3Spring框架API文档的压缩包,文件名以-javadoc结尾。整个Spring框架由21个模块组成,该目录下将看到Spirng为每个模块都提供了三个压缩包。
schemas:该目录下包含了Spring各种配置文件的XML Schema文档。
readme.txt、notice.txt、license.txt等说明性文档。
2.将libs目录下所需要模块的class文件的JAR包复制添加到项目的类加载路径中。
3.Spring核心容器必须依赖于common-logging的JAR包。下载commons-logging-x.x.x.jar添加到项目的类加载路径中。
4.如果需要发布使用了Spring框架的Java Web项目,还需要将Spring框架的JAR包和commons-logging-x.x.x.jar添加到Web应用的WEB-INF路径下。
7.2.2 使用Spring管理Bean
Spring 核心容器的理论很简单: Spring 核心容器就是一个超级大工厂,所有的对象(包括数据源、Hibernate、SessionFactory等基础性资源)都会被当成Spring核心容器管理的对象------Spring把容器中的一切对象成为Bean。
Class : Axe
package edu.pri.lime.bean; //Spring 对Bean类没有任何要求,只要它是个Java类即可。 public class Axe { public String chop(){ return "使用斧头砍柴"; } }
Class : Person
package edu.pri.lime.bean; public class Person { private Axe axe; // 设置注入所需的setter方法 public void setAxe(Axe axe) { this.axe = axe; } public void userAxe(){ System.out.println("我打算去砍点柴火"); // 调用axe的chop() 方法, // 表明Person对象依赖于axe对象。 // 这种A对象需要调用B对象方法的情形,被成为依赖。 System.out.println(axe.chop()); } }
为项目增加XML配置文件来管理容器中的Bean。Spring对XML配置文件的文件名没有任何要求。
<?xml version="1.0" encoding="UTF-8"?> <!-- Spring 配置文件的根元素,使用Spring-beans-4.0.xsd语义约束 --> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!-- 配置名为person的Bean。其实现类是edu.pri.lime.bean.Person类 --> <bean id="person" class="edu.pri.lime.Person"> <!-- 控制调用setAxe()方法,将容器中的axe Bean 作为传入参数 --> <property name="axe" ref="axe"/> </bean> <!-- 配置名为axe的Bean,其实现类是edu.pri.lime.bean.Axe类 --> <bean id="axe" class="edu.pri.lime.Axe"/> <!-- 配置名为win的Bean,其实现类是javax.swing.JFrame类 --> <bean id="win" class="javax.swing.JFrame"/> <!-- 配置名为date的Bean,其实现类是java.util.Date类 --> <bean id="date" class="java.util.Date"/> </beans>
配置文件中的<bean.../>元素默认以反射方式来调用类的无参构造函数
<bean id="person" class="edu.pri.lime.Person"> <property name="axe" ref="axe"/> </bean>
String idStr = ...; //解析<bean.../>元素的id属性得到该字符串值为person //解析<bean.../>元素的class属性得到该字符串为edu.pri.lime.bean.person String classStr = ...; Class clazz = Class.forName(classStr); Object obj = clazz.newInstance(); //container代表Spring容器 container.put(idStr,obj);
每个<bean.../》元素默认驱动Spring调用该类无参数的构造器来创建实例,并将该实例作为Spring容器中的Bean。
在Spring配置文件中配置Bean时,class属性的值必须是Bean实现类的完整类名,不能是接口,不能是抽象类(除非有特殊配置),否则Spring无法使用反射创建该类的实例。
<property.../>子元素通常用于作为<bean.../>元素的子元素,驱动Spring在底层以反射执行一次setter方法。name属性决定执行哪个setter方法,value或ref决定执行setter方法的传入参数。
如果传入参数是基本类型及其包装类、String等类型,则使用value属性指定传入参数。
如果以容器中其他Bean作为传入参数,则使用ref属性指定传入参数。
一旦创建处理Bean,Spring会立即根据<property.../>子元素执行setter方法,即<bean.../>元素驱动Spring调用构造器创建对象,<property.../>子元素驱动Spring执行setter方法,先后执行。
String nameStr = ...; //解析<property.../>元素的name属性得到该字符串值为axe String refStr = ...; //解析<property.../>元素的ref属性得到该字符串值为axe String setterName = "set" + nameStr.substring(0,1).toUpperCase() + nameStr.substring(1); //生成将要调用的setter方法名 //获取Spring容器中名为refStr的Bean,该Bean将会作为传入参数。 Object paramBean = container.get(refStr); Method setter = clazz.getMethod(setterName, paramBean.getClass()); setter.invoke(obj,paramBean);
ApplicationContext是Spring容器最常用的接口,该接口有如下两个实现类
ClassPathXmlApplicationContext : 从类加载路径系搜索配置文件,并根据配置文件来创建Spring容器。
FileSystemXmlApplicationContext : 从文件系统的相对路径或绝对路径下去搜索配置文件,并根据配置文件来创建Spring容器。
对于Java项目而言,类加载路径总是稳定的,因此通常总是使用ClassPathXmlApplicationContext创建Spring容器。
package edu.pri.lime.main; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import edu.pri.lime.bean.Person; public class BeanTest { public static void main(String[] args) throws Exception{ // 床架Spring容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); // 获取id为person的Bean Person per = ctx.getBean("person", Person.class); // 调用userAxe()方法 per.userAxe(); } }
Spring 容器获取Bean对象主要有两个方法。
Object getBean(String id) : 根据容器中Bean的id来获取指定Bean,获取Bean之后需要进行强制类型转换。
T getBean(String id, Class<T> requiredType) : 根据容器中Bean的id来获取指定类型的Bean。无须强制类型转换。