Spring IOC
- IOC(控制反转)和DI(依赖注入)
依赖注入或控制反转的定义中,调用者不负责被调用者的实例创建工作,该工作由Spring框架中的容器来负责,它通过开发者的配置来判断实例类型,创建后再注入调用者。由于Spring容器负责被调用者实例,实例创建后又负责将该实例注入调用者,因此称为依赖注入。而被调用者的实例创建工作不再由调用者来创建而是由Spring来创建,控制权由应用代码转移到了外部容器,控制权发生了反转,因此称为控制反转。
在我看来二者其实实质相同都是在说将控制权转交给spring容器以配置和注解的方式完成类的依赖注入
依赖注入的两种方式
1.设值注入:IOC容器通过setter方法注入被依赖的实例
2.构造注入:通过构造器来设置依赖关系的实例
Spring容器启动的基本条件:
- Spring的框架类包
- Bean的配置信息
- Bean的实现类
其中Bean的配置信息包含三种:xml配置文件,configure类以及注解Autowrite
xml配置文件及其相关
1.根元素
<beans.../>
<bean.../>
2.Bean的作用域通过bean的scope属性指定
- singleton:单例模式,在整个Spring IOC容器中,使用singleton定义的Bean将只有一个实例;
- prototype:原型模式,每次容器通过GetBean()方法获取该作用域的Bean都会产生一个新的Bean实例;
- request:每次HTTP请求都会生成新的不同的Bean实例;
- session:对于每次HTTP session,该作用域的Bean都将产生不同的Bean实例;
- global session:每个全局的HTTP session都对应一个Bean实例
(注:在不指定作用域的情况下,默认为singleton)
3.配置依赖
Spring可以为任何java对象注入任何类型的属性(需要该对象提供了相应的setter方法)
<bean id="id" class="xxx.AClass">
<property name="aaa" value="va1">
<property name="bbb" value="va2">
</bean>
Spring会为每个bean元素创建一个java对象,而这每一个java对象就是一个Bean实例,创建java实例如下:
//获取xxx.AClass类的Class对象
Class x=Class.forName("xxx.AClass");
//创建xxx.AClass类的实例
Object bean=x.newInstance();
创建该实例后,Spring容器遍历所有bean元素里的property子元素,每有一个property子元素就会为该bean实例调用一次setter方法
//获得aaa属性对应的setter方法
String setName1= "set" + "Aaa";
Method setMethod1=x.getMethod(setName1,va1.getClass());
//调用bean中的setAaa()方法
setMethod1.invoke(bean,va1)
这样,Spring就根据配置文件的信息创建了java实例并为其注入属性值。
4.合作者bean
Bean的属性也有可能会是容器中的另一个Bean实例,这是不能使用value属性而是使用ref元素,同时可以指定两个属性:
- bean:引用不在同一份xml配置文件中其他Bean实例的id属性值;
- local:引用同一份xml配置文件中其他Bean实例的id属性值;
同时Spring提供了自动装配合作者Bean(不需要使用ref元素指定依赖Bean)的方法,即设置bean元素的autowrite属性:
- no:不适用自动装配,这时必须通过ref元素指定;
- byName:根据属性名称自动装配,BeanFactory查找容器内的全部Bean,找出其中id属性和该属性同名的Bean来注入;(如果没有找到则不进行任何注入)
- byType:根据属性类型自动装配,BeanFactory查找容器内的全部Bean,如果正好有一个和依赖属性类型相同的Bean,就自动注入这个属性,如果有多个符合该类型的Bean,则会抛出异常,如果没有符合该类型的Bean,则不进行任何注入;
Configure类
Spring3.0开始允许开发者使用java类进行配置(使用注解的形式)
资源访问
Spring为资源访问提供了一个Resource接口,根据不同的底层资源提供了大量的实现类:
访问网络资源
Urlresource,主要用于访问之前通过URL类访问过的资源对象:
file:访问文件系统
http:用于通过HTTP协议访问资源
ftp:用于通过FTP协议访问资源访问类加载路径下的资源
对于Web应用,ClassPathResource可以自动搜索WEB-INF/classes下的资源文件,不需要使用绝对路径访问访问文件系统资源
FileSystemResource和java提供的File类作用茶币不打,都可以用于访问文件系统资源访问应用相关资源
Spring提供ServletContextResource类来访问Web Context下相对路径下的资源;当程序试图直接通过File来访问Web Context下相对路径下的资源时,应该先使用ServletContextResource的getRealPath()方法来取得资源的绝对路径,再用绝对路径创建File对象访问字节数组资源
Spring提供了InputStreamResource来访问二进制输入流资源,ByteArrayResource用于直接访问字节数组资源(InputStreamResource的效率并不好,故尽量使用ByteArrayResource或者FileSystemResource代替它)