[干货]FactoryBean的意义,bean创建源码分析,与@Bean的区别探讨

737 阅读2分钟

FactoryBean的意义

FactoryBean是一个工厂Bean,可以创造某一类型的Bean。BeanFactory是Spring容器中的一个基本类也是很重要的一个类,在BeanFactory中可以创建和管理Spring容器中的Bean,它对于Bean的创建有一个统一的流程。

FactoryBean一个很重要的作用就是可以让我们自定义Bean的创建过程。

FactoryBean接口介绍

public interface FactoryBean<T> {

   @Nullable
   T getObject() throws Exception;

   @Nullable
   Class<?> getObjectType();

   default boolean isSingleton() {
      return true;
   }

}

getObject()是工厂方法,用来生产对象。getObjectType()返回生产对象类型。isSingleton用来指定生产的对象是否为单例。

FactoryBean生成的对象如何注入

下面我们写一个生产自行车的FactoryBean,再把生产出来自行车注入到一个类里面使用。

@Component
public class MyFactoryBean implements FactoryBean {


    @Override
    public Bicycle getObject() throws Exception {
        Bicycle bicycle = new Bicycle();
        bicycle.setName("自行车");
        bicycle.setLunzi(4);
        bicycle.setFdj("体力驱动");
        return bicycle;
    }

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

自行车类:

/**注意不要加@Component注解或者@Service注解**/
public class Bicycle {

    private  int lunzi;
    private   String  name;
    private   String  fdj;
  
    public int getLunzi() {
        return lunzi;
    }

    public void setLunzi(int lunzi) {
        this.lunzi = lunzi;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getFdj() {
        return fdj;
    }

    public void setFdj(String fdj) {
        this.fdj = fdj;
    }
}

将自行车注入:

@RestController
@RequestMapping("/dyProxy")
public class LaController {
    @Resource
    private Bicycle bicycle;
  
    @RequestMapping("/test7")
    public String test7 (){
        System.out.println("test7:"+JSON.toJSONString(bicycle));
        return "";
    }
}

源码调试:

需要创建的bean的名称为myFactoryBean:

生成的Bean为:

最终创建出来的是Bycycle类型的Bean

创建FactoryBean内对象的源码分析:

我们就上面的代码中的bicycle实例创建过程,给大家分析一下:

1.调用getBean方法,参数name为myFactoryBean

2.从三级缓存中按名称查找该FactoryBean,在三级缓存中没有找到

3.调用getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法

sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
	});

createBean方法会将FactoryBean实例创建出来,然后在getSingleton方法中会

调用FactoryBean实例的getObject()方法,将bicycle创建出来。

4.最后将bicycle返回。

FactoryBean和@Bean的区别探讨

@Configuration和@Bean注解配合,也可以用来创建bean,和FactoryBean的作用基本相同。但是@Bean功能更强大一些,可以支持懒加载,设置作用域等。

希望大家留言探讨!