最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

FactoryBean使用及真實(shí)應(yīng)用場景分享

 更新時(shí)間:2026年05月31日 09:56:35   作者:起名困難綜合癥  
這段文章詳細(xì)介紹了FactoryBean在Spring中的應(yīng)用,包括其定義、使用方法以及在Spring Boot中的實(shí)例,同時(shí),探討了如何利用FactoryBean整合MyBatis,簡化了MyBatis與Spring的集成過程,通過FactoryBean,第三方庫可以被優(yōu)雅地加載到Spring容器中,提升了系統(tǒng)的靈活性和可擴(kuò)展性

一、FactoryBean是什么?

FactoryBean是spring提供的一個(gè)接口,可以通過它創(chuàng)建自定義對象工廠,將其注入spring容器后,會將其本身和其所要?jiǎng)?chuàng)建的bean一同注入容器。他和工廠模式中的工廠本質(zhì)上來沒有太大的區(qū)別,只不過一個(gè)是由spring 容器管理,一個(gè)是使用者自己管理。

FactoryBean中有三個(gè)方法如下:

public interface FactoryBean<T> {

	/**
	 * The name of an attribute that can be
	 * {@link org.springframework.core.AttributeAccessor#setAttribute set} on a
	 * {@link org.springframework.beans.factory.config.BeanDefinition} so that
	 * factory beans can signal their object type when it can't be deduced from
	 * the factory bean class.
	 * @since 5.2
	 */
	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";


	/**
	 返回我們所要?jiǎng)?chuàng)建的bean
	 * Return an instance (possibly shared or independent) of the object
	 * managed by this factory.
	 * <p>As with a {@link BeanFactory}, this allows support for both the
	 * Singleton and Prototype design pattern.
	 * <p>If this FactoryBean is not fully initialized yet at the time of
	 * the call (for example because it is involved in a circular reference),
	 * throw a corresponding {@link FactoryBeanNotInitializedException}.
	 * <p>As of Spring 2.0, FactoryBeans are allowed to return {@code null}
	 * objects. The factory will consider this as normal value to be used; it
	 * will not throw a FactoryBeanNotInitializedException in this case anymore.
	 * FactoryBean implementations are encouraged to throw
	 * FactoryBeanNotInitializedException themselves now, as appropriate.
	 * @return an instance of the bean (can be {@code null})
	 * @throws Exception in case of creation errors
	 * @see FactoryBeanNotInitializedException
	 */
	@Nullable
	T getObject() throws Exception;

	/**
	返回我們要?jiǎng)?chuàng)建bean的class類型
	 * Return the type of object that this FactoryBean creates,
	 * or {@code null} if not known in advance.
	 * <p>This allows one to check for specific types of beans without
	 * instantiating objects, for example on autowiring.
	 * <p>In the case of implementations that are creating a singleton object,
	 * this method should try to avoid singleton creation as far as possible;
	 * it should rather estimate the type in advance.
	 * For prototypes, returning a meaningful type here is advisable too.
	 * <p>This method can be called <i>before</i> this FactoryBean has
	 * been fully initialized. It must not rely on state created during
	 * initialization; of course, it can still use such state if available.
	 * <p><b>NOTE:</b> Autowiring will simply ignore FactoryBeans that return
	 * {@code null} here. Therefore, it is highly recommended to implement
	 * this method properly, using the current state of the FactoryBean.
	 * @return the type of object that this FactoryBean creates,
	 * or {@code null} if not known at the time of the call
	 * @see ListableBeanFactory#getBeansOfType
	 */
	@Nullable
	Class<?> getObjectType();

	/**
	是否為單例
	 * Is the object managed by this factory a singleton? That is,
	 * will {@link #getObject()} always return the same object
	 * (a reference that can be cached)?
	 * <p><b>NOTE:</b> If a FactoryBean indicates to hold a singleton object,
	 * the object returned from {@code getObject()} might get cached
	 * by the owning BeanFactory. Hence, do not return {@code true}
	 * unless the FactoryBean always exposes the same reference.
	 * <p>The singleton status of the FactoryBean itself will generally
	 * be provided by the owning BeanFactory; usually, it has to be
	 * defined as singleton there.
	 * <p><b>NOTE:</b> This method returning {@code false} does not
	 * necessarily indicate that returned objects are independent instances.
	 * An implementation of the extended {@link SmartFactoryBean} interface
	 * may explicitly indicate independent instances through its
	 * {@link SmartFactoryBean#isPrototype()} method. Plain {@link FactoryBean}
	 * implementations which do not implement this extended interface are
	 * simply assumed to always return independent instances if the
	 * {@code isSingleton()} implementation returns {@code false}.
	 * <p>The default implementation returns {@code true}, since a
	 * {@code FactoryBean} typically manages a singleton instance.
	 * @return whether the exposed object is a singleton
	 * @see #getObject()
	 * @see SmartFactoryBean#isPrototype()
	 */
	default boolean isSingleton() {
		return true;
	}

}

二、使用

在使用FactoryBean的時(shí)候,大多數(shù)是于spring提供的其他接口一起使用

1.創(chuàng)建我們需要的bean及其builder

代碼如下(示例):

@Data
public class Customize {

    private String id;

    private String name;

    private int age;

    private String address;

    private String phone;
}

public class CustomizeBuilder {

    private Customize customize;

    public CustomizeBuilder builder() {
        customize = new Customize();
        return this;
    }

    public CustomizeBuilder id(String id) {
        customize.setId(id);
        return this;
    }

    public CustomizeBuilder name(String name) {
        customize.setName(name);
        return this;
    }

    public CustomizeBuilder age(int age) {
        customize.setAge(age);
        return this;
    }

    public CustomizeBuilder address(String address) {
        customize.setAddress(address);
        return this;
    }

    public CustomizeBuilder phone(String phone) {
        customize.setPhone(phone);
        return this;
    }

    public Customize build() {
        return customize;
    }
}

2.創(chuàng)建FactoryBean的實(shí)例

實(shí)現(xiàn)了InitializingBean 的 afterPropertiesSet()方法,該方法將在實(shí)現(xiàn)類的屬性加載完畢后調(diào)用。

代碼如下(示例):

@Component
public class CustomizeFactoryBean implements FactoryBean<Customize> , InitializingBean {

    private Customize customize;

    @Override
    public Customize getObject() throws Exception {
        return customize;
    }

    @Override
    public Class<?> getObjectType() {
        return Customize.class;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (customize == null){
            customize= new CustomizeBuilder().builder()
                    .id("1")
                    .name("sun")
                    .age(18)
                    .address("beijing")
                    .phone("123456789")
                    .build();
        }
    }
}

之后我們在測試類中進(jìn)行測試

@SpringBootTest
class SpringBeanApplicationTests {
    @Autowired
    private Customize customize;
    @Autowired
    private CustomizeFactoryBean customizeFactoryBean;
    @Test
    public void contextLoads() throws Exception {
        System.out.println(customizeFactoryBean);
        System.out.println(customizeFactoryBean.getObject());
        System.out.println(customize);
    }
}

輸出:

com.agp.springbean.factorybean.CustomizeFactoryBean@5a592c70
Customize(id=1, name=sun, age=18, address=beijing, phone=123456789)
Customize(id=1, name=sun, age=18, address=beijing, phone=123456789)

對springboot進(jìn)行調(diào)試得到注入FactoryBean工廠得到的默認(rèn)對象就是其要?jiǎng)?chuàng)建的對象,可以通過&+factoryBeanName得到真實(shí)的bean工廠


整合mybatis

上述我們雖然通過@Component 將工廠注入到spring容器中,但是他真正的用法卻不是這樣。因?yàn)橄胍砸粋€(gè)bean我們可以通過很多種方式去完成。這種方法明顯是比較麻煩的,官方也不推薦使用spring相關(guān)注解注入。

下面來看看mybatis-spring是如何將spring整合mybatis的。

mybatis是如何運(yùn)行的?

mybatis的核心組件是 SqlSession,我們所有的sql操作都要使用這個(gè)接口完成。sqlSession又是由SqlSessionFactory構(gòu)建的。通過build方法創(chuàng)建出了SqlSessionFactory,即得到SqlSession。

具體解析過程這里不做介紹

public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
    try {
      // 傳入配置文件,創(chuàng)建一個(gè)XMLConfigBuilder類
      XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
      // 分兩步:
      // 1、解析配置文件,得到配置文件對應(yīng)的Configuration對象
      // 2、根據(jù)Configuration對象,獲得一個(gè)DefaultSqlSessionFactory
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        reader.close();
      } catch (IOException e) {
      }
    }
  }

由上述代碼可知,只要我們擁有了SqlSessionFactory就擁有了mybatis的所有能力,剩下的就是怎么把SqlSessionFactory集成到spring中

在mybatis-spring中有這樣的一個(gè)Factorybean

public class SqlSessionFactoryBean
    implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ContextRefreshedEvent>{
	private SqlSessionFactory sqlSessionFactory;
....

  @Override
  public void afterPropertiesSet() throws Exception {
    notNull(dataSource, "Property 'dataSource' is required");
    notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
    state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
        "Property 'configuration' and 'configLocation' can not specified with together");

    this.sqlSessionFactory = buildSqlSessionFactory();
  }
    @Override
  public SqlSessionFactory getObject() throws Exception {
    if (this.sqlSessionFactory == null) {
      afterPropertiesSet();
    }

    return this.sqlSessionFactory;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Class<? extends SqlSessionFactory> getObjectType() {
    return this.sqlSessionFactory == null ? SqlSessionFactory.class : this.sqlSessionFactory.getClass();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isSingleton() {
    return true;
  }
}

通過了buildSqlSessionFactory()來創(chuàng)建了SqlSessionFactory(),具體細(xì)節(jié)不做介紹。相信到了這里在結(jié)合我們在使用spring結(jié)合mybatis時(shí)的配置,大家都應(yīng)該能了解如何使用了,通過xml或者javaConfig的方式就SqlSessionFactoryBean加入到spring容器中將第三方的mybatis 集成到容器中,然后使用mybatis了

總結(jié)

FactoryBean主要是用來在spring初始化的過程中創(chuàng)建bean的工廠,個(gè)人理解它更像一個(gè)插件的接口??梢詫⒌谌降念悆?yōu)雅的加載到spring容器中??赡苓€有其他功能有待開發(fā)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot應(yīng)用中出現(xiàn)的Full GC問題的場景與解決

    SpringBoot應(yīng)用中出現(xiàn)的Full GC問題的場景與解決

    這篇文章主要為大家詳細(xì)介紹了SpringBoot應(yīng)用中出現(xiàn)的Full GC問題的場景與解決方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-04-04
  • maven?helper?jar包沖突的幾種解決方法

    maven?helper?jar包沖突的幾種解決方法

    maven Helper是排查jar包沖突的一大利器,jar包沖突大部分是由于引用了同一個(gè)jar的不同版本而導(dǎo)致的,本文主要介紹了maven?helper?jar包沖突的幾種解決方法,感興趣的可以了解一下
    2024-03-03
  • Java實(shí)現(xiàn)pdf文件合并的使用示例

    Java實(shí)現(xiàn)pdf文件合并的使用示例

    本文主要介紹了Java實(shí)現(xiàn)pdf文件合并的使用示例,主要是將需要合并的pdf文件都拷貝到指定目錄a中,調(diào)用該工具類將該目錄作為第一個(gè)參數(shù),第二個(gè)參數(shù)傳入輸出文件對象即可,感興趣的可以了解一下
    2023-12-12
  • Spring boot集成Kafka+Storm的示例代碼

    Spring boot集成Kafka+Storm的示例代碼

    這篇文章主要介紹了Spring boot集成Kafka+Storm的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • Spring Cloud Zuul自定義過濾器的實(shí)現(xiàn)

    Spring Cloud Zuul自定義過濾器的實(shí)現(xiàn)

    這篇文章主要介紹了自定義Spring Cloud Zuul過濾器的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Idea+maven搭建SSH(struts2+hibernate5+spring5)環(huán)境的方法步驟

    Idea+maven搭建SSH(struts2+hibernate5+spring5)環(huán)境的方法步驟

    這篇文章主要介紹了Idea+maven搭建SSH(struts2+hibernate5+spring5)環(huán)境的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • spring中的特殊注解@RequiredArgsConstructor詳解

    spring中的特殊注解@RequiredArgsConstructor詳解

    這篇文章主要介紹了spring中的特殊注解@RequiredArgsConstructor,包括注解注入,構(gòu)造器注入及setter注入,結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • 詳解Spring Data JPA動態(tài)條件查詢的寫法

    詳解Spring Data JPA動態(tài)條件查詢的寫法

    本篇文章主要介紹了Spring Data JPA動態(tài)條件查詢的寫法 ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • Java編寫實(shí)現(xiàn)多人聊天室

    Java編寫實(shí)現(xiàn)多人聊天室

    這篇文章主要為大家詳細(xì)介紹了Java編寫實(shí)現(xiàn)多人聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Java利用文件輸入輸出流實(shí)現(xiàn)文件夾內(nèi)所有文件拷貝到另一個(gè)文件夾

    Java利用文件輸入輸出流實(shí)現(xiàn)文件夾內(nèi)所有文件拷貝到另一個(gè)文件夾

    這篇文章主要介紹了Java實(shí)現(xiàn)文件夾內(nèi)所有文件拷貝到另一個(gè)文件夾,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03

最新評論

乐安县| 车致| 天峨县| 奉贤区| 监利县| 营山县| 萨迦县| 平定县| 大石桥市| 景德镇市| 麻江县| 姚安县| 雷山县| 石门县| 娱乐| 上饶市| 五原县| 镇沅| 紫金县| 怀柔区| 陕西省| 广昌县| 上犹县| 治多县| 锦州市| 林甸县| 木里| 嘉禾县| 滦平县| 七台河市| 和平区| 普兰店市| 宜州市| 儋州市| 宜兰市| 城口县| 柘荣县| 临漳县| 临朐县| 辛集市| 新郑市|