zoukankan      html  css  js  c++  java
  • 关于Spring中的ApplicationContext,BeanFactory,FactoryBean整理

    • BeanFactory

    BeanFactory是Bean的工厂,Spring的顶层核心接口,它为Spring的IoC功能提供了基础,它使用了简单工厂,负责生产Bean,Bean的定义信息

    BeanFactory的类图如下:

    • ApplicationContext

    从上面的类图可以看出ApplicationContext包含了BeanFactory的所有功能,ApplicationContext更值得推荐,除了一些特定的场景,例如在资源受限的设备上运行的内嵌的应用;

    使用GenericApplicationContext及其子类AnnotationConfigApplicationContext作为自定义引导的常见实现, 这些是Spring用于所有常见目的的核心容器的主要入口点:加载配置文件,触发类路径扫描,以编程方式注册bean定义和带注解的类,以及(从5.0开始)注册功能bean定义;

    从使用角度上说,ApplicationContext是面向用户的,它不仅能提供Bean和调用工厂生产Bean,还能提供一系列的服务(如国际化,加载Bean定义,监听器等);在ApplicationContext(例如GenericApplicationContext实现)中,按照约定(即通过bean名称或bean类型,特别是后处理器)检测到几种bean, 而普通的DefaultListableBeanFactory对任何特殊bean都是不可知的;

    BeanFactory与ApplicationContext功能对比  

    Feature

    BeanFactory

    ApplicationContext
    Bean Bean实例化/装配 Yes Yes
    集成的生命周期管理 No Yes
    自动注册 BeanPostProcessor No Yes
    自动注册 BeanFactoryPostProcessor No Yes
    便利的 MessageSource 访问 (国际化) No Yes
    内置ApplicationEvent 发布机制 No Yes
    • FactoryBean

    一般情况下,Spring通过反射机制利用bean的class属性指定实现类来实例化bean;在某些情况下,实例化bean过程比较复杂,如果按照传统的方式,则需要在<bean>@Bean 中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案;Spring为此提供了一个org.springframework.beans.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化bean的逻辑

    FactoryBean是单例对象的工厂bean,通过FactoryBean可以把bean实例注入到容器中;

    接口如下:

    getObject 返回由FactoryBean创建的bean实例,如果isSingleton()返回true,则该实例会放到Spring容器的单实例缓存池中;
    
    isSingleton 返回由FactoryBean创建的bean实例的作用域是singleton还是prototype;
    
    getObjectType 返回FactoryBean创建的bean类型;
    

      

    当容器启动完成,Bean本身的实例是没有创建的,只会创建FactoryBean的实例,如果需要获取Bean实例本身,当调用getBean需要在id前加个&

    FactoryBean实例化Bean的流程如下:

    FactoryBean测试如下:

    @Test
    public void mainTest13() {
    	AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
    			MainConfig10.class);
    
    	System.out.println("IOC容器创建完成...");
    
    	// 调用FactoryBean#getBean方法,入参为Bean id,得到的对象为FactoryBean#getObjectType的对象
    	// FactoryBean要获取工厂Bean本身,需要在id前加个&
    	// org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance
    	Object factoryBean1 = context.getBean("demoFactoryBean");
    	Object factoryBean2 = context.getBean("demoFactoryBean");
    	System.out.println("factoryBean1==factoryBean2 :" + (factoryBean1 == factoryBean2));
    	System.out.println("bean的类型:" + factoryBean1.getClass());
    
    	Object factoryBean3 = context.getBean("&demoFactoryBean");
    	System.out.println("bean的类型:" + factoryBean3.getClass());
    }
    

      

    @Configuration
    public class MainConfig10 {
    	@Bean
    	public DemoFactoryBean demoFactoryBean() {
    		return new DemoFactoryBean();
    	}
    }
    

      

    public class DemoFactoryBean implements FactoryBean<Person> {
    
    	/**
    	 * 是否单例进行控制
    	 * @return
    	 */
    	@Override
    	public boolean isSingleton() {
    		return true;
    	}
    
    	/**
    	 * 返回对象,把对象放到容器中
    	 * @return
    	 * @throws Exception
    	 */
    	@Override
    	public Person getObject() throws Exception {
    		return new Person();
    	}
    
    	/**
    	 * 返回对象类型
    	 * @return
    	 */
    	@Override
    	public Class<?> getObjectType() {
    		return Person.class;
    	}
    }
    

      

    执行结果如下:

    参考:[https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-beanfactory]

  • 相关阅读:
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Bound mismatch: The typae CertificateDirectory is not a valid substitute for the bounded parameter <M extends Serializable>
    Duplicate property mapping of contactPhone found in
  • 原文地址:https://www.cnblogs.com/coder-zyc/p/15178304.html
Copyright © 2011-2022 走看看