前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring中的FactoryBean和BeanFactory

Spring中的FactoryBean和BeanFactory

原创
作者头像
诺浅
修改2020-08-21 17:44:59
3690
修改2020-08-21 17:44:59
举报
文章被收录于专栏:工具使用工具使用

缘起

在spring的常见面试题中,经常会被问及FactoryBean和BeanFactory的区别与联系。这两个类虽然长得很像,但是他们的作用确实完全不像。其实这二者本就并没有什么关系,要是一定要说说关系,那或者就是二者都是一个接口吧。但要是说区别却能说出一大堆

  • BeanFactory 以Factory结尾,表示它是一个工厂类,用于管理Bean的一个工厂,在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。
  • FactoryBean 以Bean结尾,就是一个Bean,但这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。BeanFactory外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fj4cJo1T-1587805016676)(http://www.bxoon.com/upload/2020/3/image-2a976aeb208b449cb2927d9a606c27ee.png) 可以看到,对应BeanFactory来说,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖等等,反正就是对Bean的管理基本都靠他,但她是个接口,Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等。FactoryBean外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qhHVLiTl-1587805016678)(http://www.bxoon.com/upload/2020/3/image-0348b670bce84ee8a4434ce9df01ecc1.png) 可以看到在该接口中定义了以下3个方法:
  • T getObject():返回由FactoryBean创建的Bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中单实例缓存池中;
  • boolean isSingleton():返回由FactoryBean创建的Bean实例的作用域是singleton还是prototype;
  • Class<T> getObjectType():返回FactoryBean创建的Bean类型。

那么这个类的使用场景是什么呢?一般情况下,Spring通过反射机制利用<bean>的class属性指定实现类实例化Bean,但这种实例化Bean的方式看起来似乎有点笨拙。我举一个简单的例子,比如你的项目里面需要根据一个参数来判定具体要实例化哪个Bean,Class A或者Class B. 那么你会怎么做呢?可能你会把这两个类都实例化出来,然后业务中根据参数来调用Class A or Class B。但更好的实现方式如下

代码语言:txt
复制
public class C implements FactoryBean {

    @Value("${icd.version}")
    private String icdVersion;

    @Override
    public Object getObject() throws Exception {
        if (xxx) {
            return SpringManager.getBean(A.class);
        } else{
            return SpringManager.getBean(B.class);
        }
    }

    @Override
    public Class<?> getObjectType() {
	//A和B的共同父类
        return xxx.class;
    }

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

SpringManager

代码语言:txt
复制
@Component
public class SpringManager implements ApplicationContextAware {

    private static ApplicationContext context = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return context;
    }

    public static Object getBean(String name) {
        return context.getBean(name);
    }

    public static <T> T getBean(Class<T> clazz) {
        return context.getBean(clazz);
    }
}

这样我们外面只需要用SpringManager.getBean(C)的方式就可以获取到Class A or Class B了,完美。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 缘起
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档