上一章对Spring作一个快速入门的教程,其中只是简单的提到了IOC的特性。本章便对Spring的IOC进行一个详解。主要从三个方面开始:基于xml文件的Bean配置,基于注解的Bean配置和IOC容器Bean的生命周期。java
首先是applicationContext.xml文件,这但是核心文件。
配置一个bean,须要一个id去惟一标识它,用class指定Bean对象的路径,做用域默认是单例。
经过prototype进行属性赋值,name是属性名,value是值,也能够用ref引用对象,用list,map设置集合。
用SpEL表达式语言赋值,用p命名空间简化赋值,用继承和依赖简化代码。spring
<?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:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 配置一个 bean bean中有一个id,且id是惟一的。若不指名则为该类的类名并首字母小写。 property 中有一个name,其name就是生产了setter方法的属性,value即是其值。 --> <!-- Bean 的做用域 singleton:单例,默认值,容器初始化建立bean实例,在整个生命周期内只建立一个bean。 prototype:原型,容器初始化不建立bean实例,每次请求的时候会建立一个新的bean --> <bean id="entity" class="com.itdragon.spring.my.Entity" scope="prototype"> <!-- 属性赋值 属性注入使用 <property> 元素, 使用 name 属性指定 Bean 的属性名称,value 属性或 <value> 子节点指定属性值 --> <property name="intValue" value="1"></property> <!-- 引用bean 细节: 1. 用ref 是引用外部bean 2. 也能够直接写在当前bean里面,这就是内部bean, 内部bean是不能被外部引用 --> <property name="spELEntity" ref="spELEntity"></property> <!-- 构造器注入 构造器注入在 <constructor-arg> 元素里声明属性, <constructor-arg> 中没有 name 属性,按照构造器参数顺序赋值 细节: 1. 也能够用index(按索引匹配入参),和type(按类型匹配入参)去指定赋值。其实是没有必要的 2. 使用构造器注入的前提是 entity 被初始化。 3. 特殊字符,须要用 <![CDATA[内容]]> 这属于xml语法 --> <constructor-arg value="1.1" /> <constructor-arg > <value><![CDATA[<ITDragon>]]></value> </constructor-arg> <property name="listValue"> <list> <value>欢迎阅读</value> <value>ITDragon</value> <value>的博客!</value> </list> </property> <property name="mapValue"> <map> <entry key="one" value="1"></entry> <entry key="two" value="2"></entry> </map> </property> </bean> <!-- SpEL 表达式语言, #{…} 做为定界符, 操做和java类似--> <bean id="spELEntity" class="com.itdragon.spring.my.SpELEntity"> <property name="intSpel" value="#{1}"></property> <property name="floatSpel" value="#{entity.intValue + 0.2}"></property> <property name="stringSpel" value="#{'Spring4基础教程'}"></property> <property name="bSpel" value="#{2 >= 1}"></property> </bean> <!-- 使用 p 命名空间 给Entity 对象 的intValue 字段设置 为2 ,根据名称匹配SpEL对象 自动装配 autowire (不经常使用) byName(根据名称自动装配): 必须将目标 Bean 的名称和属性名设置的彻底相同.反之不能 byType(根据类型自动装配): 若 IOC 容器中有多个与目标 Bean 类型一致的 Bean. 在这种状况下, 不能执行自动装配. --> <bean id="entity2" class="com.itdragon.spring.my.Entity" p:intValue="2" autowire="byName" /> <!-- 继承 依赖 若是 被继承的bean 不想被继承,则要加上 abstract="true" 依赖:若是被依赖的bean,没有实例化,则会报错。若是有多个依赖需用","分开 --> <bean id="entity3" class="com.itdragon.spring.my.Entity" parent="entity" depends-on="spELEntity" /> <!-- 使用外部属性文件 在Spring操做数据库的时候再讲 --> </beans>
实体类Entity和SpELEntity数据库
import java.util.List; import java.util.Map; public class Entity { private int intValue; private float floatValue; private String stringValue; private SpELEntity spELEntity; private Map<String, Object> mapValue; private List<Object> listValue; public Entity() { } public Entity(float floatValue, String stringValue) { this.floatValue = floatValue; this.stringValue = stringValue; } public int getIntValue() { return intValue; } public void setIntValue(int intValue) { this.intValue = intValue; } public float getFloatValue() { return floatValue; } public void setFloatValue(float floatValue) { this.floatValue = floatValue; } public String getStringValue() { return stringValue; } public void setStringValue(String stringValue) { this.stringValue = stringValue; } public SpELEntity getSpELEntity() { return spELEntity; } public void setSpELEntity(SpELEntity spELEntity) { this.spELEntity = spELEntity; } public Map<String, Object> getMapValue() { return mapValue; } public void setMapValue(Map<String, Object> mapValue) { this.mapValue = mapValue; } public List<Object> getListValue() { return listValue; } public void setListValue(List<Object> listValue) { this.listValue = listValue; } @Override public String toString() { return "Entity [intValue=" + intValue + ", floatValue=" + floatValue + ", stringValue=" + stringValue + ", spELEntity=" + spELEntity + ", mapValue=" + mapValue + ", listValue=" + listValue + "]"; } }
public class SpELEntity { private int intSpel; private float floatSpel; private boolean bSpel; private String stringSpel; public int getIntSpel() { return intSpel; } public void setIntSpel(int intSpel) { this.intSpel = intSpel; } public float getFloatSpel() { return floatSpel; } public void setFloatSpel(float floatSpel) { this.floatSpel = floatSpel; } public boolean isbSpel() { return bSpel; } public void setbSpel(boolean bSpel) { this.bSpel = bSpel; } public String getStringSpel() { return stringSpel; } public void setStringSpel(String stringSpel) { this.stringSpel = stringSpel; } @Override public String toString() { return "SpELEntity [intSpel=" + intSpel + ", floatSpel=" + floatSpel + ", bSpel=" + bSpel + ", stringSpel=" + stringSpel + "]"; } }
测试Main方法。首先要建立一个容器,而后经过bean的id获取到实例,这样就能够开始相关的操做。其中entity,entity2,entity3对应三块不一样的知识点。express
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { /** * ClassPathXmlApplicationContext:从 类路径下加载配置文件,建议用该方法 * FileSystemXmlApplicationContext: 从文件系统中加载配置文件 */ // 1. 建立 Spring 的 IOC 容器 ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); /** * entity 属性注入,构造器注入,对象引用,集合,SpEL,(重点) * entity2 自动装配和P命名空间 * entity3 继承和依赖,做用域 */ // 2. 从 IOC 容器中获取 bean 的实例 Entity entity = (Entity) ctx.getBean("entity"); // 3. 使用 bean System.out.println(entity.toString()); // System.out.println(ctx.getBean("entity") == ctx.getBean("entity")); 使用 prototype 打印的是false ctx.close(); } }
Entity [intValue=1, floatValue=1.1, stringValue=<ITDragon>, spELEntity=SpELEntity [intSpel=1, floatSpel=1.2, bSpel=true, stringSpel=Spring4基础教程], mapValue={one=1, two=2}, listValue=[欢迎阅读, ITDragon, 的博客!]]
相对于xml的配置,注解的方式显得异常简单。主要分两个步骤
第一步:在applicationContext.xml文件设置扫描包的范围segmentfault
<?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:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" 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/util http://www.springframework.org/schema/util/spring-util-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置自动扫描指定目录下的包 resource-pattern="xxx/*.class" 属性过滤特定的类 --> <context:component-scan base-package="com.itdragon.spring.my" > <!-- annotation 是针对指定的类 和 assignable 是针对全部继承或者扩展该类的类--> <!-- context:exclude-filter 只排除expression里面的内容 <context:exclude-filter type="annotation" expression=""/> --> <!-- context:include-filter 只包含expression里面的内容 需配合 use-default-filters="false"(默认是true) 一块儿使用 <context:include-filter type="annotation" expression=""/> --> </context:component-scan> </beans>
第二步:在对象上用注解。这四几个注解的做用同样,只是为告终构清晰,取的名字不一样罢了。
使用方法很简单:直接在类上加注解便可。无参数的状况,bean的id默认是小写字母开头的类名。也能够指定参数@Commponent("指定参数"),那bean的id就是指定参数。
@Component: 基本注解, 标识了一个受 Spring 管理的组件
@Respository: 标识持久层组件
@Service: 标识服务层(业务层)组件
@Controller: 标识表现层组件app
public interface AnnoRepository { public void hello(); }
import org.springframework.stereotype.Repository; @Repository public class AnnoRepositoryImp implements AnnoRepository{ @Override public void hello() { System.out.println("AnnoRepository : hello!"); } }
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class AnnoService { @Autowired private AnnoRepository annoRepository; public void hello() { System.out.println("AnnoService : hello!"); annoRepository.hello(); } }
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class AnnoController { @Autowired private AnnoService annoService; public void execut() { System.out.println("AnnoController : hello !"); annoService.hello(); } }
这里还有一个注解Autowired, <context:component-scan> 元素会自动组件装配被Autowired修饰的对象。
测试类:虽然applicationContext.xml中没有annoController的bean配置,但咱们有注解!ide
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); AnnoController annoController = (AnnoController) ctx.getBean("annoController"); annoController.execut(); ctx.close(); } }
AnnoController : hello ! AnnoService : hello! AnnoRepository : hello!
有没有以为基于注解的bean配置比基于xml的bean配置简单不少。测试
step1 实例化,经过构造器建立 Bean 实例
step2 赋值,为 Bean 的属性设置值
step3 init-method,调用 Bean 的初始化方法(init-method)
step4 destroy-method,当容器关闭时, 调用 Bean 的销毁方法(destroy-method)this
以上代码都是笔者亲测可用的,不要嫌麻烦,麻烦是学很差的,若是有什么问题和建议能够留言,我会及时处理。http://blog.csdn.net/qq_19558...spa