IOC 容器
IoC即控制反转,他使得组件或类之间尽量的形成一种松的耦合结构,创建类都是Ioc容器来干,Spring 容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。把对象的创建、初始化、销毁交给 spring 来管理,而不是由开发者控制,实现控制反转。
所谓IoC,就是通过容器来控制业务对象之间的依赖关系,而非传统实现中,由代码直接操控。这也就是“控制反转”概念的所在:控制权由应用代码中转到了外部容器,控制权的转移,就是反转。控制权转移带来的好处就是降低了业务对象之间的依赖程度。
Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件。这些对象被称为 Spring Beans,
Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序
Spring通过一个配置文件描述了Bean及Bean之间的依赖关系,利用Java语言的反射功能实例化Bean并建立Bean之间的依赖关系。
Spring的IoC容器在完成这些底层工作的基础上,还提供了Bean实例缓存、生命周期管理、Bean实例代理、事件发布、资源装载等高级服务
谈及IOC容器我们应该从BeanFactory和ApplicationContext接口分析。
BeanFactory
BeanFactory是Spring最核心的接口,他提供了高级的IoC配置机制。BeanFactory使管理不同类型的java对象成为了可能,应用上下文(ApplicationContext)建立在BeanFactory的基础之上。它还提供了国际化支持和框架事件体系,更易于创建实际应用。一般称BeanFactory为IoC容器,而称ApplicationContext为应用上下文。但有时为了行文方便,也将ApplicationContext称为Spring容器。
它主要的功能是为依赖注入 (DI) 提供支持,这个容器接口在 org.springframework.beans.factory.BeanFactor 中被定义。
BeanFactory 和相关的接口,比如BeanFactoryAware、 DisposableBean、InitializingBean,仍旧保留在 Spring 中,主要目的是向后兼容已经存在的和那些 Spring 整合在一起的第三方框架实现了IoC控制,可以称为IoC容器通过xml配置文件或.properties中读取Javabean的定义,来实现Javabean配置和管理创建。
可以通过BeanFactory接口方法getBean来使用Bean名字,从而当获取Bean时,如果需要获取的Bean是prototype类型的,用户还可以为这个prototype类型的Bean生成指定构造函数的对应参数。这使得在一定程度上可以控制生成prototype类型的Bean。有了BeanFactory的定义,用户可以执行以下操作:
❑ 通过接口方法containsBean让用户能够判断容器是否含有指定名字的Bean。
❑ 通过接口方法isSingleton来查询指定了名字的Bean是否是Singleton类型的Bean。对于Singleton属性,用户可以在BeanDefinition中指定。
❑ 通过接口方法isPrototype来查询指定了名字的Bean是否是prototype类型的。与Singleton属性一样,这个属性也可以由用户在BeanDefinition中指定。
❑ 通过接口方法isTypeMatch来查询指定了名字的Bean的Class类型是否是特定的Class类型。这个Class类型可以由用户来指定。
❑ 通过接口方法getType来查询指定了名字的Bean的Class类型。
❑ 通过接口方法getAliases来查询指定了名字的Bean的所有别名,这些别名都是用户在BeanDefinition中定义的。这些定义的接口方法勾画出了IoC容器的基本特性
XmlBeanFactory可以通过xml读取装配JavaBean在调用getBean()方法时不会实例化任何对象只有在JavaBean需要创建时才会分配资源空间,
-
第一步利用框架提供的 XmlBeanFactory() API 去生成工厂 bean 以及利用 ClassPathResource() API 去加载在路径 CLASSPATH 下可用的 bean 配置文件。
XmlBeanFactory() API 负责创建并初始化所有的对象,即在配置文件中提到的 bean。 -
第二步利用第一步生成的 bean 工厂对象的 getBean() 方法得到所需要的 bean。这个方法通过配置文件中的 bean ID 来返回一个真正的对象,该对象最后可以用于实际的对象。一旦得到这个对象,就可以利用这个对象来调用任何方法
例如通过BeanFactory装载配置文件,启动Spring IoC容器:
Resource re=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(re);
Test test =factory.getBean("test");
> 在xml文件中配置如下:
> <!引入beans.dtd>
> <beans>
> < bean id="test" class="com.test.Test">
> </beans>
复制代码
XmlBeanFactory通过Resource装载Spring配置信息并启动IoC容器,然后就可以通过BeanFactory.getBean(beanName)方法从IoC容器中获取Bean了。通过BeanFactory启动IoC容器时,并不会初始化配置文件中定义的Bean。初始化动作发生在第一个调用时,对于单实例(singleton)的Bean来说,BeanFactory会缓存Bean实例,所以第二次使用getBean()获取Bean时,将直接从IoC容器的缓存中获取Bean实例。
Spring在DefaultSingletonBeanRegistry类中提供了一个用于缓存单实例Bean的缓存器,它是一个用HashMap实现的缓存器,单实例的Bean以beanName为键保存在这个HashMap中。值得一提的是,在初始化BeanFactory时,必须为其提供一种日志框架,这里使用Log4J,即在类路径下提供Log4J配置文件,这样启动Spring容器才不会报错
ApplicationContext:
ApplicationContext是Spring中较高级的容器和beanFactory类似,他可以加载配置文件定义的bean,将所有的bean集中在一起,当请求时分配bean,扩展了BeanFactory容器并添加了国际化,生命周期,事件,监听,提供了BeanFactory的所有特性而且允许用户使用更多的声明方式. ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置的方式实现.
有三个实现的类:
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
WebApplicationContext
ClassPathXmlApplicationContext:
从当前类路径中检索配置文件并装载他来创建容器的实例
ApplicationContext context=new ClassPathXmlApplicationContext(String configLocation);
FileSystemXmlApplicationContext:
如果配置文件放置在文件系统的路径下,则可以优先考虑使用这个类。不是从类路径中获取配置信息,而是通过参数指定配置文件的位置,可以获取类路径之外的资源,该容器从 XML 文件中加载已被定义的 bean。
在这里,你需要提供给构造器 XML 文件的完整路径
ApplicationContext context=new FileSystemXmlApplicationContext(String configLocation);
WebApplicationContext:
WebApplicationContext是专门为Web应用准备的,它允许从相对于Web根目录的路径中装载配置文件,完成初始化工作。从WebApplicationContext中可以获得ServletContext的引用,整个Web应用上下文对象将作为属性放置到ServletContext中,以便Web应用环境可以访问Spring应用上下文。Spring专门为此提供一个工具类WebApplicationContextUtils,通过该类的getWebApplicationContext(ServletContext sc) 方 法,即 可 以 从ServletContext中 获 取WebApplicationContext实例
有两种方法在servlet中使用
-
1.在servlet中的web.xml配置Spring 的 ContextLoaderListener的监听器,
-
2.修改web.xml在配置文件中添加一个servlet定义使用Spring的ContextLoaderServlert类
ApplicationContext的初始化和BeanFactory的初始化有一个重大的区别:BeanFactory在初始化容器时,并未实例化Bean,直到第一次访问某个Bean时才实例化目标Bean;而ApplicationContext在初始化应用上下文时就实例化所有单实例的Bean。因此ApplicationContext的初始化时间会比BeanFactory稍长一些,不过稍后的调用则没有“第一次惩罚”的问题
本文使用 文章同步助手 同步