首页 > 其他分享 >Spring之FactoryBean

Spring之FactoryBean

时间:2023-02-15 11:25:31浏览次数:39  
标签:对象 Spring getObject bean FactoryBean Car public

FactoryBean

目录

一、官方说明

Interface to be implemented by objects used within a BeanFactory which are themselves factories for individual objects. If a bean implements this interface, it is used as a factory for an object to expose, not directly as a bean instance that will be exposed itself.

由BeanFactory中使用的对象实现的接口,这些对象本身就是单个对象的工厂。如果一个bean实现了这个接口,它将被用作一个要公开的对象的工厂,而不是直接作为一个将要公开的bean实例。

也就是说,FactoryBean本身是一个Bean,但是却是不公开,换句话说,就是不经常使用这个bean,而是使用这个工厂对象产生bean。

NB: A bean that implements this interface cannot be used as a normal bean. A FactoryBean is defined in a bean style, but the object exposed for bean references (getObject()) is always the object that it creates.

一个bean实现了FactoryBean接口,不能够做为一个正常的bean。使用FactoryBean可以来定义bean的风格,但是这个bean对象是FactoryBean调用getObject()方法创建出来的对象。

FactoryBeans can support singletons and prototypes, and can either create objects lazily on demand or eagerly on startup. The SmartFactoryBean interface allows for exposing more fine-grained behavioral metadata

FactoryBean可以支持单例和原型bean,并且可以根据需要或在启动时提前创建bean对象。SmartFactoryBean接口允许公开更细粒度的行为元数据

This interface is heavily used within the framework itself, for example for the AOP org.springframework.aop.framework.ProxyFactoryBean or the org.springframework.jndi.JndiObjectFactoryBean. It can be used for custom components as well; however, this is only common for infrastructure code.

该接口在框架本身中大量使用,例如AOP org.springframework.AOP.framework.ProxyFactoryBean或org.springfframework.jndi.JndiObjectFactoryBean。它也可以用于自定义组件;然而,这仅适用于基础结构代码。

The container is only responsible for managing the lifecycle of the FactoryBean instance, not the lifecycle of the objects created by the FactoryBean. Therefore, a destroy method on an exposed bean object (such as java.io.Closeable.close() will not be called automatically. Instead, a FactoryBean should implement DisposableBean and delegate any such close call to the underlying object.

容器只负责管理FactoryBean实例的生命周期,而不是FactoryBean创建的对象的生命周期。因此,不会自动调用公开的bean对象(例如java.io.Closable.close())上的destroy方法。相反,FactoryBean应该实现DisposableBean并将任何此类关闭调用委托给基础对象。

二、FactoryBean组织结构

/**
 * 实现此接口的bean不能用作普通bean。此bean暴露的对象是通过getObject()创建的对象,而不是它自身
 */
public interface FactoryBean<T> {
    /**
     * 返回此工厂管理的对象的实例(可能是共享的或独立的,取决于isSingleton()的返回值)
     */
    @Nullable
    T getObject() throws Exception;
  
    /**
     * 返回此FactoryBean创建的对象类型,
     */
    @Nullable
    Class<?> getObjectType();
  
    /**
     * 该工厂管理的对象是否为单例?
     * 如果是(return true),getObject()总是返回同一个共享的实例,该对象会被BeanFactory缓存起来
     * 如果是(return false),getObject()返回独立的实例
     * 一般情况下返回true
     */
    default boolean isSingleton() {
        return true;
    }
}

说的简单点,FactoryBean是BeanFactory支持的、用来暴露bean实例的接口。

三、FactoryBean使用

public class Car {}
@Component
public class MyFactoryBean implements FactoryBean<Car> {
  @Override
  public Car getObject() throws Exception {
    return new Car();
  }
  
  @Override
  public Class<?> getObjectType() {
    return Car.class;
  }
}

测试类:

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(LiAppCOnfig.class);
applicationContext.refresh();
System.out.println(applicationContext.getBean("myFactoryBean").getClass().getSimpleName());
System.out.println(applicationContext.getBean("&myFactoryBean").getClass().getSimpleName());

打印输出结果:

Car
MyFactoryBean

通过正常的myFactoryBean(beanName)获取得到的是FactoryBean中产生的对象;而通过&myFactoryBean(&beanName)获取得到的是FactoryBean当前类的对象。

四、源码分析

通过源码进行分析

applicationContext.getBean("myFactoryBean")

一开始从spring容器获取名为myFactoryBean的bean,类型确实是:MyFactoryBean,但是后面又经过getObjectForBeanInstance来真正获取我们需要的对象

看下具体的源码:

然后调用具体的方法

那么这里就有一个细节问题:FactoryBean调用getObject()方法产生的对象只走了后置处理方法,没有走初始化前、初始化方法,而是直接走了初始化后方法。

4.1、制造场景

public class Car implements InitializingBean {
	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("初始化方法");
	}
}

调用测试方法检测,发现控制台打印输出的是:

Car
MyFactoryBean

并没有执行对应的afterPropertiesSet初始化方法。

从这里也证明了,FactoryBean调用getObject()方法产生的对象并不是一个Spring真正意义上的Bean

标签:对象,Spring,getObject,bean,FactoryBean,Car,public
From: https://www.cnblogs.com/likeguang/p/17122073.html

相关文章

  • Spring Colud之Loadbalancer
    一、负载均衡有两大门派,服务端负载均衡和客户端负载均衡网关层负载均衡网关层负载均衡也被称为服务端负载均衡,就是在服务集群内设置一个中心化负载均衡器,比如APIGatewa......
  • CentOS中使用Dockerfile部署带websocket的SpringBoot的jar包
    场景CentOS7中使用Dockerfile部署后台jar包在上面使用Dockerfile定制的镜像部署了一个普通的jar包, 如果是jar包里面包含websocket的使用,流程也是一样。websocket所使用的......
  • Spring6之HTTP Interface分析
    目录1HTTPInterface1.1引言1.2示例1.2.1创建服务端1.2.2SpringBoot工程1.3深入分析1.3.1GetExchange(HttpExchange)1.3.2UserApiService实例创建1.4其他特性1HT......
  • 随堂笔记8-spring循环依赖
    spring循环依赖//A依赖了BclassA{publicBb;}//B依赖了AclassB{publicAa;}以上就会出现循环依赖,解决方法,二级三级缓存bean的生命周期:spring扫描cla......
  • 【Spring-boot-route(十九)Spring-boot-admin监控服务+(二十)spring-boot-route(二十)Spring
    ​​SpringBootAdmin​​​不是Spring官方提供的模块,它包含了​​Client​​​和​​Server​​两部分。server部分提供了用户管理界面,client即为被监控的服务。client需要......
  • 【工具使用】IDEA Spring源码报Unable to find method ‘org.gradle.api.artifacts.re
    1 前言IDEA拉Spring源码,源码是Gradle管理依赖的,但是报错Unabletofindmethod'org.gradle.api.artifacts.result.ComponentSelectionReas我的IDEA有2019、2021的2 ......
  • Java:SpringBoot整合Knife4j(Swagger)提供接口文档
    spring-boot版本2.7.71、引入Maven坐标pom.xml<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId>......
  • SpringBoot常用注解大全
    常用注解概览这里整理了一张SpringBoot常用注解的思维导图,本文主要讲解这些注解的用法。 组件相关注解@ComponentScan默认扫描当前包及其子包下面被@component,@Cont......
  • spring-注解开发
    一.注解实现自动装配jdk1.5开始支持注解,spring2.5开始支持注解!要使用注解须知:1.导入约束xmlns:context="http://www.springframework.org/schema/context"http://......
  • SpringFramework学习日记
    初识Spring,Spring的系统架构1、Spring全家桶是一个很nb的生态,我们可以用他开发自己想要的格式的功能CoreContainer是Spring的容器,java的对象交给Spring的容器来管理AO......