spring中FactoryBean是什么bean


前言

在spring中FactoryBean絕對是一種神奇的存在,和BeanFactory經常混淆,而且成為面試過程中經常被問到的問題,其實FactoryBean和BeanFactory很好理解,掌握一定的技巧即可。

初識

FactoryBean翻譯過來是工廠Bean,BeanFactory翻譯過來是Bean工廠,前者是bean工廠beanFactory中的一個bean,只不過這個bean和一般的bean不一樣,它有着自己的特殊之處,特殊在什么地方那,在spring中提供了FactoryBean的接口,

package org.springframework.beans.factory;

import org.springframework.lang.Nullable;


public interface FactoryBean<T> {

    
    @Nullable
    T getObject() throws Exception;

    
    @Nullable
    Class<?> getObjectType();

    
    default boolean isSingleton() {
        return true;
    }

}

FactoryBean接口很簡單,就提供了三個方法getObject、getObjectType、isSingleton。就是這三個方法卻成為了spring中很多功能的基礎,搜索整個spring的源碼可以找到很多FactoryBean,除了spring自身提供的以外,在和一些框架進行集成的時候,同樣有FactoryBean的影子,比如和mybatis集成的時候的SqlSessionFactoryBean,

用法

這里以springboot的環境為例演示下FactoryBean的用法,有需要源碼的可關注公眾號【北漂程序員】私聊我。

自定義FactoryBean,僅在getObject方法內自己new了一個Student對象,且返回該對象;重寫了toString方法,為了測試用。

package com.example.myDemo.component;

import com.example.myDemo.po.Student;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

@Component
public class MyFactoryBean implements FactoryBean<Student> {

    @Override
    public Student getObject() throws Exception {

        Student student=new Student();
        return student;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

    @Override
    public String toString() {
        return "MyFactoryBean{}";
    }
}

下面是Student類,很簡單就兩個屬性且重寫了toString方法,

package com.example.myDemo.po;

public class Student {
    private String name;
    private String code;

    public Student(String name, String code) {
        this.name = name;
        this.code = code;
    }

    public Student() {
    }

    @Override
    public String toString() {
        return "Student{}";
    }
}

下面就是測試的方法了,

package com.example.myDemo;

import com.example.myDemo.component.MyFactoryBean;
import com.example.myDemo.po.Student;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.ApplicationContext;

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class MyDemoApplication {

    public static void main(String[] args) {
        ApplicationContext ac=SpringApplication.run(MyDemoApplication.class, args);

        //獲得Student對象
        Student stu=(Student) ac.getBean("myFactoryBean");
        //獲得MyFactoryBean對象
        MyFactoryBean myFactoryBean=(MyFactoryBean) ac.getBean("&myFactoryBean");
        System.out.println("stu:"+stu);
        System.out.println("myFactoryBean:"+myFactoryBean);

    }

}

先看下打印結果,

打印結果很奇怪通過“myFactoryBean”獲得了Student對象,通過“&myFactoryBean”獲得了MyFactoryBean對象。為什么會這樣

功能解釋

看了上面的輸出結果很多小伙伴都很詫異,沒錯這就是FactoryBean的神奇,通俗點講FactoryBean是一個工廠bean,它是一種可以生產bean的bean,通過其getObejct方法生產bean。當然不論是FactoryBean還是FactoryBean生產的bean都是受spring管理的這點是沒有問題的,不然通過getBean方法是拿不到的。

上面講了那么多到底FactoryBean的用處是什么,前面講到FactroyBean的作用是生產一個Bean,這里有一個疑問spring就是用來生產bean和管理bean的,為什么還要有FactoryBean,FactoryBean的真正目的是讓開發者自己去定義那些復雜的bean並交給spring管理,如果bean中要初始化很多變量,而且要進行許多操作,那么使用spring的自動裝配是很難完成的,所以spring的開發者把這些工作交給了我們。一個比較常見的例子是,在mybatis和spring集成的時候便有這樣一個FactoryBean,名字叫SqlSessionFactoryBean,這個FactoryBean的目的就是返回一個spring管理的SqlSessionFactory,使用過mybatis的都知道要創建一個sqlSessionFactory需要配置很多屬性,所以便有了SqlSessionFactoryBean,下面看下SqlSessionFactoryBean,

看下sqlSessionFactoryBean的getObejct方法

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

        return this.sqlSessionFactory;
    }

getObejctType方法

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

isSingleton方法

public boolean isSingleton() {
        return true;
    }

總結

本篇文章主要帶小伙伴了解了FactoryBean這種特殊的Bean,它的作用就是生產Bean。這里有個疑問在使用getBean方法的時候,為什么傳入“myFactoryBean”和“&MyFactoryBean”兩個值返回值一個是FactoryBean生產的bean,一個是FactorBean那,下篇通過源碼來揭秘,揭秘getObjectForBeanInstance方法的那些事,歡迎關注。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM