目录
IOC控制反转/依赖注入
以前是直接创建一个属性/依赖类,如果我们依赖于某个类或服务,最简单而有效的方式就是直接在类的构造函数中新建相应的依赖类。
但是在IOC中,所有的被注入对象和依赖对象现在由IoC Service Provider统一管理。从被注入对象的角度看,与之前直接寻求依赖对象相比,依赖对象的取得方式发生了反转,控制也从被注入对象转到了IoC Service Provider那里
Spring的IoC容器就是一个提供依赖注入服务的IoC Service Provider。对于为被注入对象提供依赖注入的IoC Service Provider来说,它也同样需要知道自己所管理和掌握的被注入对象和依赖对象之间的对应关系。通用方法为xml配置文件的方式。意义在于把一个java对象和它的依赖关系以xml的形式放进容器中交给IOC容器管理。
Spring的IoC容器是一个提供IoC支持的轻量级容器,能完成对象创建,依赖注入,AOP等功能。IOC容器通俗讲的意义在于当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。
Spring提供了两种IOC容器类型: BeanFactory和ApplicationContext
BeanFactory和ApplicationContext的区别和联系
BeanFactory:
1、基础类型IoC容器
2、默认采用延迟初始化策略( lazy-load)。只有当客户端对象需要访问容器中的某个受管对象的时候,才对该受管对象进行初始化以及依赖注入操作。
3、容器启动初期速度较快,所需要的资源有限。对于资源有限,并且功能要求不是很严格的场景, BeanFactory是比较合适的IoC容器选择。
4、不能作为ResourceLoader直接加载资源。
ApplicationContext:
1、间接继承自BeanFactory,在BeanFactory的基础上构建,是相对比较高级的容器实现
2、ApplicationContext所管理的singleton对象,在该类型容器启动之后,默认全部初始化并绑定完成。prototype类型的对象不会自动初始化。
3、所以,相对于BeanFactory来说, ApplicationContext要求更多的系统资源,同时,因为在启动时就完成所有初始化,容器启动时间较之BeanFactory也会长一些。在那些系统资源充足,并且要求更多功能的场景中,ApplicationContext类型的容器是比较合适的选择。
3、直接继承ResourcePatternResolver,间接继承ResourceLoader,可以作为ResourceLoader直接加载资源。
创建容器
BeanFactory container = new XmlBeanFactory(new ClassPathResource("配置文件路径"));
container.getBean("");
ClassPath实现类构造时写的是相对路径(默认在src下)
ApplicationContext container = new ClassPathXmlApplicationContext("配置文件路径");
container.getBean("");
FileSystem实现类构造时写的是绝对路径
ApplicationContext container = new FileSystemXmlApplicationContext("配置文件路径");
container.getBean("");
XML文件的配置
如之前所说,BeanFactory也采用xml外部配置文件的方式管理容器内对象。Spring 2.x之前, XML配置文件采用DTD( Document Type Definition)实现文档的格式约束。 2.x之后,引入了基于XSD( XML Schema Definition)的约束方式。
XML文件的配置
beans
<beans>作为所有<bean>的“统帅”,它拥有相应的属性( attribute)对所辖的<bean>进行统一的默认行为设置,包括如下几个。
Bean
id属性,通过id属性来指定当前注册对象的beanName是什么
class属性,指定其类型。大部分情况下,该属性是必须的,除了抽象配置模板
autowire属性,依赖自动绑定,有五个值。no,byname,bytype,constructor,autodetect
lazy-init属性,控制ApplicationContext对singleton对象是否延迟初始化
parent属性,当前bean继承了parent bean的所有注入,父子类的关系
abstrat属性,可以不指定class,ApplicationContext会在容器启动的时候就对其管理的所有bean进行实例化,只有标志为abstract的bean除外。
singleton属性,生命周期,true或者false。指定singleton和prototype。
标记为拥有singleton scope的对象定义,在Spring的IoC容器中只存在一个实例,所有对该对象的调用(getbean()方法)将共享这个实例,该实例从初始化之后,将一直存活到容器退出,也就是说,它与IoC容器“几乎”拥有相同的“寿命”
声明为拥有prototype scope的bean定义,容器在接到该类型对象的请求(getbean()方法)的时候,会每次都重新生成一个新的对象实例给请求方,容器每次返回给请求方一个新的对象实例之后,就不归容器管理,其生命周期终止。
init-method属性
destroy-method属性
Bean对象的创建方式:
1、直接class创建(默认无参构造方法)
2、构造方法创建
使用时,用name或index表明一个构造方法时的哪个参数;用type表明在有多个参数个数相同的构造方法的哪个参数,如果这些参数名字相同,用type属性区分不同构造方法;用value或ref表明哪种具体的值
3、工厂方法创建,前提是在java代码中有工厂方法的实现。
静态工厂方法,属性id,class,factory-method
非静态工厂方法,属性id,factory-bean,factory-method
4、FactoryBean创建,前提是需要在java代码中创建出FactoryBean
FactoryBean本质是生产bean对象的工厂,它本身也是一个bean对象,他有三个属性明确了所要造的bean的类型,对象实例,是否singleton三个信息。。
依赖注入的方式:
1、setter注入
<property>标签,前提是在java代码中其对象必须要有setter方法。其中name属性指对象属性的名字,value或ref表明具体值。
2、构造方法注入
<constructor-arg>标签,属性name,type,index,value,ref
如果不想用ref
使用时,用name或index表明一个构造方法时的哪个参数;用type表明在有多个参数个数相同的构造方法的哪个参数,如果这些参数名字相同,用type属性区分不同构造方法;用value或ref表明哪种具体的值
3、自动注入(bean的autowire属性:五种)
no,byname,bytype,constructor,autodetect。
注意byname和bytype都是在已经配置为bean对象中寻找,如果属性没有配置成bean对象,那么找不到。
autodetect优先考虑byType的自动绑定模式。否则,会使用constructor模式
4、方法注入(用在单例范围的bean中出现原型范围的依赖的时候:lookup-method、实现BeanFactoryAware接口)