spring IoC (IDEA)——BeanFactory和ApplicationContext

1.BeanFactory

BeanFactory 是 Spring 的“心脏”,是Spring框架最核心的接口, 定义了IoC的基本功能,主要定义了getBean方法。

我们一般称BeanFactory为IoC容器,从用途的角度来说,是面向Spring框架的基础设施,面向Spring本身,一般在开发中几乎不会使用。

BeanFactory接口

Spring bean容器的根接口。提供获取bean,是否包含bean,是否单例与原型,获取bean类型,bean 别名的方法。 

BeanFactory的三个子接口

HierarchicalBeanFactory:提供父容器的访问功能 

ListableBeanFactory:提供了批量获取Bean的方法 

AutowireCapableBeanFactory:在BeanFactory基础上实现对已存在实例的管理 

ConfigurableBeanFactory

ConfigurableListableBeanFactory 

继承了上述的所有接口,增加了其他功能:比如类加载器,类型转化,属性编辑器,BeanPostProcessor,作用域,bean定义,处理bean依赖关系, bean如何销毁… 

实现类DefaultListableBeanFactory

实现了ConfigurableListableBeanFactory,实现上述BeanFactory所有功能。它还可以注册BeanDefinition。

案例演示

添加依赖

 <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.18.RELEASE</version>
    </dependency>

创建beans.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="s1" class="com.etc.entity.Student">
        <property name="no" value="2015001001"></property>
        <property name="name" value="张三"></property>
        <property name="gender" value="男"></property>
    </bean>
</beans>

实体类省略get和set

    private String no;
    private String name;
    private String gender;

    public Student() {
        System.out.println("初始化");
    }

测试类

package com.etc.test;

import com.etc.entity.Student;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionReader;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class TestBeanFactory {

    @Test
    public void testGetBean(){
        //XmlBeanFactory在3.1以后已经被废弃,不再推荐使用
        //BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beans.xml"));
        //修改为以下的方法
        Resource resource = new ClassPathResource("beans.xml");
        BeanFactory bf = new DefaultListableBeanFactory();
        BeanDefinitionReader bdr = new XmlBeanDefinitionReader((BeanDefinitionRegistry) bf);
        bdr.loadBeanDefinitions(resource);
        System.out.println("初始化BeanFactory完成");
        //通过BeanFactory启动IoC容器时,不会创建bean的实例,在调用getBean方法时才会创建Bean的实例
        Student student1 = (Student)bf.getBean("s1");
        System.out.println(student1);
        Student student2 = (Student)bf.getBean("s1");
        System.out.println(student2);
    }
}

输出结果,实体类后加载完成

九月 08, 2018 12:23:01 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans.xml]
初始化BeanFactory完成
初始化
Student{no='2015001001', name='张三', gender='男'}
Student{no='2015001001', name='张三', gender='男'}

2.ApplicationContext

如果说BeanFactory是Spring的心脏,那么ApplicationContext就是完整的身躯了,ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置(或者注解)实现。

我们一般称ApplicationContext为应用上下文,也称为Spring容器,它是面向使用Spring框架的开发者,几乎所有的应用场合都是使用ApplicationContext而非底层的BeanFactory。

案例演示

创建applicationContext.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="s1" class="com.etc.entity.Student">
        <property name="no" value="2015001001"></property>
        <property name="name" value="张三"></property>
        <property name="gender" value="男"></property>
    </bean>
</beans>

测试类

package com.etc.test;

import com.etc.entity.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestApplicationContext {

    @Test
    public void testGetBean(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("初始化ApplicationContext完成");
        Student student1 = (Student) context.getBean("s1");
        System.out.println(student1);
        Student student2 = (Student) context.getBean("s1");
        System.out.println(student2);
    }
}

运行结果,实体类先加载完成

九月 08, 2018 12:21:52 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@38cccef: startup date [Sat Sep 08 00:21:52 CST 2018]; root of context hierarchy
九月 08, 2018 12:21:52 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
初始化
初始化ApplicationContext完成
Student{no='2015001001', name='张三', gender='男'}
Student{no='2015001001', name='张三', gender='男'}

3.两者区别

(1)BeanFactory采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的Spring的配置问题。而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。 相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。

(2)Applicationcontext比 BeanFactory 加入了一些更好使用的功能,beanFactory 的许多功能需要通过编程实现而 Applicationcontext 可以通过配置实现。比如后处理 bean, Applicationcontext 可以直接配置在配置文件即可而 beanFactory 这要在代码中显示的写出来才可以被容器识别。

(3)BeanFactory主要是面向Spring 框架的基础设施,面向 Spring 自己。而 Applicationcontex 主要面向 Spring 框架的开发者,在我们开发时都是使用 ApplicationContext 而 BeanFactory 。

猜你喜欢

转载自blog.csdn.net/Milan__Kundera/article/details/82504576