Spring学习笔记(一)IOC与Spring基础xml配置
2016-09-09 14:38
741 查看
1. IOC与DI
IOC(Inversion of Control):控制反转DI(Dependency Injection):依赖注入
“控制反转”和“依赖注入”其实是同一个概念:
改变由调用者创建被调用者的过程。被调用者依赖Spring容器注入到调用者中。
之所以出现两个名词是因为“控制反转”比较难懂,听者不明所以,所以有了更形象的“依赖注入”。
2. IOC的发展历程
3. Spring容器
简单说,就是Spring中生成“Bean”的工厂,并管理“Bean”的生命周期。Spring的配置文件说到底就是“Bean”的配置。“Bean”是Spring管理的基本单位,不仅仅指简单的POJO类,组件也是“Bean”,例如数据源、事务管理器,Hibernate的SessionFactory。
Spring中内置了两种基础DI容器:
BeanFactory和
ApplicationContext。
ApplicationContext继承了
BeanFactory的所有特性。关系如下图:
BeanFactory应用与内存、CPU资源受限的场合,一般情况下优先使用
ApplicationContext,因为它除了拥有
BeanFactory支持的所有功能,还可以:
载入多个配置文件
提供国际化支持
事件机制
默认初始化所有的singleton Bean(
BeanFactory则不会)
常用的
ApplicationContext的子类如下图:
XmlWebApplicationContext:面向Web应用
AnnotationConfigApplicationContext:基于注解存储DI元数据
XmlPortlerApplicationContext:面向Portal应用
ClassPathXmlApplicationContext、FileSystemXmlApplicationContext:适用于各种场景
4. 注入方式
Spring的注入方式有三种:设值注入、构造器注入、工厂注入。设置注入和构造器注入
实体类:public class Person{ public String name; private Axe axe; public Person(Axe axe, String name) { System.out.println("Person 的带参构造方法"); this.axe = axe; this.name = name; } /** * 砍柴 */ public void choopWood() { if(axe!=null){ axe.useAxe(); } } public void info() { System.out.println("This person's name is " + name); } public void setName(String name) { this.name = name; } public void setAxe(Axe axe) { this.axe = axe; } }
注入类:
public interface Axe { public void useAxe(); } public class StoneAxe implements Axe { public void useAxe() { System.out.println(test + "石斧砍柴很慢"); } } public class IronAxe implements Axe{ public void useAxe() { System.out.println("铁斧砍柴很快"); } }
Spring配置文件:
<?xml version="1.0" encoding="UTF-8"?> <!--spring配置文件的根元素,使用spring-beans-3.0.xsd语义约束(.xsd都是语言约束文件) xmlns:p配置可使用p标签更方便的配置属性 --> <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" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- id 表示你这个组件的名字,class表示组件类;autowire为是否自动加载; lazy-init为是否懒加载,即applicationContext容器启动不自动加载 --> <bean id="person" class="test.wsz.spring.bean.Person" lazy-init="true" autowire="byType" > <!--自定义set注入,name 为成员变量名称,value为自定义的值 --> <property name="name" value="wsz"></property> <!--引用set注入,name 为成员变量名称,ref为注入bean的id --> <property name="axe" ref="ironaxe"></property> <!--构造注入,index为形参的位置,从0开始,ref为注入bean的id --> <constructor-arg ref="stoneaxe" index="0" /> <constructor-arg value="wsz" index="1" /> </bean> <!--其余实体Bean--> <bean id="ironaxe" class="test.wsz.spring.bean.IronAxe" /> <bean id="stoneaxe" class="test.wsz.spring.bean.StoneAxe" /> </beans>
从配置的注释可以知道“设置注入”和“构造器注入”的配置方法。
“设置注入”会调用成员变量的
setXXX方法。
“构造器注入”会调用类对应的构造方法。
测试代码:
ApplicationContext context=new ClassPathXmlApplicationContext("config/spring-config.xml"); Person person=context.getBean("person",Person.class); person.info(); person.choopWood();
工厂方式注入
工厂方式注入有好几种,这里只举“静态工厂注入”和“工厂Bean的例子”静态工厂注入
先创建一个工厂类:
/** * 静态简单工程类 */ public class AxeFactory { /** * 获取产品的方法,根据形参返回不同的产品 */ public static Axe getAxe(String type) { if("stone".equals(type)) return new StoneAxe(); else if("iron".equals(type)) return new IronAxe(); return new StoneAxe(); } }
再修改之前的类当成产品类:
public class StoneAxe implements Axe { private String test; public StoneAxe() { System.out.println("调用StoneAxe的无参构造方法"); } public void useAxe() { System.out.println(test + "石斧砍柴很慢"); } public void setTest(String test) { this.test = test; } }
再在xml文件中进行对应的配置:
<!--静态工厂类获取Bean,class为工厂类;factory-method为工厂获取方法--> <bean id="stone" class="test.wsz.spring.factory.AxeFactory" factory-method="getAxe"> <!--设置传入工厂类获取产品方法形参的值--> <constructor-arg value="stone"/> <!--设置注入产品Bean的属性--> <property name="test" value="哈哈,"></property> </bean>
根据配置我们可以知道,现在设置的工厂类返回
StoneAxe,我们进行测试:
Axe axe=context.getBean("stone",Axe.class); axe.useAxe();
输出:
哈哈,石斧砍柴很慢
工厂Bean注入
这种方式配置比较简单。只需要创建一个实现了Spring工厂接口的工厂类,再将这个工厂类配置在
<Beans />中即可。
工厂类,需实现接口的三个方法:
public class AxeBeanFactory implements FactoryBean<Axe>{ Axe axe=null; /** * 返回产品 */ public Axe getObject() throws Exception { if(axe==null){ axe=new StoneAxe(); } return axe; } /** * 返回产品的类型 */ public Class<?> getObjectType() { return Axe.class; } /** * 是否单例 */ public boolean isSingleton() { return true; } }
xml配置:
<!--容器中的工厂Bean--> <bean id="stonefactory" class="test.wsz.spring.factory.AxeBeanFactory" />
值得注意的是,虽然
<Bean />中配置的好像是工厂类,但实现了Spring工厂接口的该类,最终
getBean()时返回的是对应的产品类。
测试代码:
Axe axe=context.getBean("stonefactory",Axe.class); axe.useAxe();
输出:
null石斧砍柴很慢
5. 配置细节
Spring的配置的参数太多,这里只总结一些常用的。复杂的等用到时再看书就行。<bean />
中的常用配置
scope:Bean的作用域,有5种:
singleton:单例模式,即整个容器里面该Bean实例只有一个,默认
prototype:原型模式,每次
getBean获取的是一个新创建的对象
request:每个HTTP请求,产生一个实例
session:每个HTTP session,产生一个实例
global session:每个全局的HTTP session,产生一个实例
lazy-init:
懒加载,当使用使用
ApplicationContext时,会自动初始化所有的
singleton的“Bean”(“Bean”默认是
singleton)。设置懒加载即不自动初始化这个类。
autowire:
自动注入。即你不用在配置中设定成员变量的注入。设置为
byType时,会自动匹配依赖类型相同的Bean,若有多个类型相同的会抛出异常。设置为
byName时,会查找id名与属性名相等的Bean。
init-method:
指定Bean依赖关系设置完毕后执行的方法。另外一种实现方式是让Bean类实现
InitializingBean接口
destory-method:
指定Bean销毁之前执行的方法。另外一种实现方式是让Bean类实现
DisposableBean接口
p名称空间:
可以看作一个语法糖,在
<beans />中添加:
xmlns:p="http://www.springframework.org/schema/p"
即可更简单的设置注入:
<bean id="person" class="test.wsz.spring.bean.Person" p:name="name" />
等效于
<bean id="person" class="test.wsz.spring.bean.Person" > <property name="name" value="wsz"></property> </bean>
6. 免XML的JAVA类配置
这个其实应用场景比较少,毕竟单纯用Java类完成复杂的Spring配置还是比较困难的。下面简单给个例子:@Configuration public class Config { @Value("大树") String personName; //注入Bean的属性中的值 @Bean(name="person") public Person person(){ Person p=new Person(); p.setName(personName); p.setAxe(stoneAxe()); return p; } @Bean(name="stoneAxe") public Axe stoneAxe() { Axe axe=new StoneAxe(); return axe; } }
除了纯粹的Java类配置,还可以在xml中引用Java类配置,或者在Java类配置中引用xml配置。有兴趣的朋友可以自行百度。
本文总结于
《疯狂JavaEE》的第七章《Spring的基本用法》
相关文章推荐
- Spring学习笔记-IOC高级特性3-用Java Config简化XML配置
- Spring 学习笔记:Ioc 基本配置
- 东软学习,hibernate初级学习的部分截图和笔记(一)-入门以及XMl基础配置
- Spring学习一:IOC(控制反转)和AOP(面向切面)的xml配置和注解方式
- Spring AOP基础知识学习——XML配置
- Spring学习——(二)IOC、DI以及常用xml配置
- Spring学习笔记二之IOC(xml实现)
- spring学习笔记(24)——xml方式配置事务
- Spring_IOC配置与应用学习笔记
- spring学习笔记(3)——配置文件applicationContext.xml的加载
- Spring-IOC配置(学习笔记)
- Spring学习笔记 在XML配置文件中使用properties文件的键值
- Spring学习笔记 使用XML配置实现Bean的auto-wiring (自动绑定)
- Spring学习笔记---2.1-IOC容器解析Bean配置信息
- Java 学习笔记04:Spring XML配置文件Bean
- spring MVC学习笔记(二) springMVC.xml配置文件解析
- Spring4 学习笔记(3)-Spring 基于 XML 的方式配置 Bean
- Spring学习笔记(一) Spring基础IOC、AOP
- Spring4 学习笔记(3)-Spring 基于 XML 的方式配置 Bean(供自己学习)
- (spring-第2回【IoC基础篇】)Spring的Schema,基于XML的配置