zoukankan      html  css  js  c++  java
  • 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方法的那些事,欢迎关注。

    一个爱写文章的程序员,欢迎关注我的公众号“北漂程序员”。我有故事,你有酒吗
  • 相关阅读:
    vector容器(一)
    螺旋数组实现
    zigzag数组实现
    HDU 1496
    HDU 1381 Crazy Search
    什么叫软核,固核,硬核?
    “杜拉拉思维模式”之六:小组面试提升术
    硬件工程师电路设计必须紧记的十大要点
    面试的“群殴”宝典
    三段式状态机 [CPLD/FPGA]
  • 原文地址:https://www.cnblogs.com/teach/p/14951920.html
Copyright © 2011-2022 走看看