Spring Ioc容器和Beans概述

一、Spring 学习

2、Spring Ioc容器和Beans概述

IoC(Inversion of Control,控制倒转),可以说是spring最核心的部分,是spring家族任意组件的基本。Ioc 本身并不能算为一种技术,而是一种思想,它使你从繁琐的对象交互中解脱出来,而专注于对象本身,更进一步突出面向对象。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。

DI(Dependency Injection,依赖注入)是目前使用较多的IOC实现方式, 常用的有两种方法:构造方法注入和setter注入。

构造注入:

<bean class="com.tcwong.bean.Cat" id="catId">
	<constructor-arg name="name" value="小黑"></constructor-arg>
	<constructor-arg name="color" value="嘿嘿"></constructor-arg>
</bean>'

setter注入:

<bean class="com.tcwong.bean.User">
	<property name="name" value="su"></property>
	<property name="age" value="20"></property>
	<property name="cats">
		<array>
			<bean class="com.tcwong.bean.Cat" >
				<constructor-arg name="name" value="tom"></constructor-arg>
				<constructor-arg name="color" value="白色"></constructor-arg>
			</bean>
		</array>
	</property>
	<property name="list">
		<list>
			<value>好好学习</value>
			<value>天天向上</value>
			<value>明天会更好</value>
		</list>
	</property>	
	<property name="map">
		<map>
			<entry key="上学" value="交学费"></entry>
			<entry key="放学" value="写作业"></entry>
			<entry key="cat" value-ref="catId"></entry>
		</map>
	</property>	
	<property name="props">
		<props>
			<prop key="date">1992</prop>
			<prop key="important">生日快乐</prop>
		</props>
	</property>		
</bean>

2.1、 IOC容器

Ioc需要实现两个技术:完成对象的构建,将其送到服务对象即完成对象的绑定。Spring提供了两种类型的容器,一个是BeanFactory,一个是ApplicationContext(可以认为是BeanFactory的扩展)。

①BeanFactory

如果没有特殊指定,默认采用延迟初始化策略(lazy-load)。只有当客户端对象需要访问容器中的某个受管对象的时候,才对该受管对象进行初始化以及依赖注入操作。所以,相对来说,容器启动初期速度较快,所需 要的资源有限。对于资源有限,并且功能要求不是很严格的场景,BeanFactory是比较合适的 IoC容器选择。我们先来看一下BeanFactory类的关系图(如下所示)

有三个很重要的部分:

  • BeanDefinition 实现Bean的定义(即对象的定义),且完成了对依赖的定义
  • BeanDefinitionRegistry ,将定义好的bean,注册到容器中(此时会生成一个注册码)
  • BeanFactory 是一个bean工厂类,从中可以取到任意定义过的bean最重要的部分就是BeanDefinition,它完成了Bean的生成过程。一般情况下我们都是通过配置文件(xml,properties)的方式对bean进行配置,每种文件都需要实现BeanDefinitionReader,因此是reader本身现了配置文字 到bean对象的转换过程。当然我们自己也可以实现任意格式的配置文件,只需要自己来实现reader即可。Bean的生成大致可以分为两个阶段:容器启动阶段和bean实例化阶段

容器启动阶段:

  • 加载配置文件(通常是xml文件)
  • 通过reader生成beandefinition
  • beanDefinition注册到beanDefinitionRegistry

bean实例化阶段:当某个bean 被 getBean()调用时bean需要完成初时化,以及其依赖对象的初始化 如果bean本身有回调,还需要调用其相应的回调函数从 上面我们也可以知道,beanDefinition(容器启动阶段)只完成bean的定义,并未完成初始化。初始是通过beanFactory的getBean()时才进行的。Spring Ioc在初始化完成之后,给了我们提供一些方法,让我们来改变一些bean的定义org.springframework.beans.factory.config.PropertyPlaceholderConfigurer:使我们可能通过配置文件的形式,配置一些参数PropertyOverrideConfigurer :则可以覆盖原本的bean参数CustomEditorConfigurer :则提供类型转换支持(配置文件都是string,它需要知道转换成何种类型)Bean的初始化过程:

如果你认为实例化的对象就是通过我们定义的类new 出来的,那就大错特错了,其实这里用到了AOP机制,生成了其代理对象(通过反射机制生成接口对象,或者是通过CGLIB生成子对象)bean的具体装载过程是由beanWrapper实现的,它继承了PropertyAccessor (可以对属性进行访问)、PropertyEditorRegistry 和TypeConverter接口 (实现类型转换,就上前面说的)。完成设置对象属性之后,则会检查是否实现了Aware类型的接口,如果实现了,则主动加载。

BeanPostprocessor 可以帮助完成在初始化bean之前或之后 帮我们完成一些必要工作,比如我们在连接数据库之前将密码存放在一个加密文件,当我们连接数据库之前,需要将密码进行加载解密。只要实现相应的接口即可。

在完成postProcessor之后,则会看对象是否定义了InitializingBean 接口,如果是,则会调用其afterProper- tiesSet()方法进一步调整对象实例的状态 ,这种方式并不常见。spring还提供了另外一种指定初始化的方式,即在bean定义中指定init-method 。当这一切完成之后,还可以指定对象销毁 的一些回调,比如数据库的连接池的配置,则销毁前需要关闭连接等。相应的可以实现DisposableBean 接口或指定destroy-method。

② ApplicationContext

ApplicationContext 容器建立BeanFactory之上,拥有BeanFactory的所有功能:

  • 1.bean的生成方式;
  • 2.扩展了BeanFactory的功能,提供了更多企业级功能的支持。

1.bean的加载方式BeanFactory提供BeanReader来从配置文件中读取bean配置。相应的ApplicationContext也提供几个读取配置文件的方式:

  • FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径
  • ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件。
  • WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。
  • AnnotationConfigApplicationContext
  • ConfigurableWebApplicationContext另外一个比较重要的是,ApplicationContext采用的非懒加载方式。它会在启动阶段完成所有的初始化,并不会等到getBean()才执行。所以,相对于BeanFactory来 说,ApplicationContext要求更多的系统资源,同时,因为在启动时就完成所有初始化,容 器启动时间较之BeanFactory也会长一些。在那些系统资源充足,并且要求更多功能的场景中, ApplicationContext类型的容器是比较合适的选择。

转载于:https://my.oschina.net/tcwong/blog/3037817

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值