工厂Bean

概述

在Spring容器中有一类特殊的bean叫工厂bean,普通的bean注入容器内的方式是通过调用其无参构造器创建一个对象导入在容器中,而工厂bean会通过FactoryBean的接口的getObject()方法将对象注册在容器中。

public interface FactoryBean<T> {
    @Nullable
    T getObject() throws Exception;

    @Nullable
    Class<?> getObjectType();

    default boolean isSingleton() {
        return true;
    }
}
复制代码

FactoryBean有三个方法:

  • getObject() //返回需要注册的对象 ,如果为单例,该实例会放到Spring容器中单实例缓存池中
  • getObjectType() //返回对象的类型
  • isSingleton() //是否是单例 ,非单例时每次创建都会返回一个新的bean

实现原理简单案例

下面通过一个简单的小案例来说明:

  • 接口

public interface Person {
    public void speak();
} 
复制代码
  • 实现类

public class Woman implements Person, BeanNameAware {

    private String beanName;

    @Override
    public void speak() {
        System.out.println("woman is talking");
    }

    @Override
    public void setBeanName(String beanName) {
        this.beanName = beanName;

    }
}
复制代码
  • 工厂bean

public class PersonFactorybean implements FactoryBean<Person> {

    private Person person;

//    返回生产的对象
    @Override
    public Person getObject() throws Exception {
       person=new Woman();
        return person;
    }

    //返回生产的类型
    @Override
    public Class<?> getObjectType() {
        return Woman.class;
    }

//    返回是否时单例
    @Override
    public boolean isSingleton() {
        return false;
    }
}
复制代码
  • 注解配置

@Configuration
public class BeanConfig {

    @Bean
    public PersonFactorybean factorybean() {
        return new PersonFactorybean();
    }
}
复制代码
  • 测试输出

@RunWith(SpringRunner.class)
@SpringBootTest
public class FactorybeanApplicationTests {

    @Test
    public void contextLoads() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
        String[] names = context.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
        Object bean = context.getBean("factorybean");
        System.out.println(bean);
    }

}
复制代码

最后输出的是com.demo.factorybean.Woman@7f02251 对象。

应用场景

在某些场景下,实例化的过程比较复杂,需要大量的配置信息。如在Spring+MyBatis的环境下,我们配置一个SqlSessionFactoryBean来充当SqlSessionFactory,如下:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="mapperLocations" value="classpath:com/cn/mapper/*.xml"></property>
</bean>
复制代码

在很多开源框架和spring集成的时候也用到FactoryBean,Spring为FactoryBean提供了70多个实现,比如Poxy、RMI等,足见其应用值广泛。

转载于:https://juejin.im/post/5cbf1e35e51d456e63760496

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值