0
点赞
收藏
分享

微信扫一扫

[Spring]浅谈BeanFactory

有态度的萌狮子 2021-12-29 阅读 67

顶层容器接口BeanFactory

BeanFactory是用于访问Spring bean容器的顶层接口,它提供一个Bean工厂的基本功能约定,而其扩展的子接口是为按职责划分的,用于特定的目的。
它里面的接口方法基本围绕一件事:getBean(),它是多态的:

  • Object getBean(String name) throws BeansException;
  • <T> T getBean(String name, Class<T> requiredType) throws BeansException;
  • Object getBean(String name, Object... args) throws BeansException;
  • <T> T getBean(Class<T> requiredType) throws BeansException;
  • <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
  • <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
  • <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
  • boolean containsBean(String name);
  • boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
  • boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
  • boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
  • boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
  • Class<?> getType(String name) throws NoSuchBeanDefinitionException;
  • String[] getAliases(String name);

FactoryBean

你会在BeanFactory中看到一个这样的变量: FACTORY_BEAN_PREFIX,它的值为&,它是用来获取FactoryBean的,如果你想访问FactoryBean,那么你可以: getBean("&beanName") .
其中,FactoryBean定义了三个接口:

  • T getObject() throws Exception;
  • Class<?> getObjectType();
  • default boolean isSingleton() {return true;}

我们通过代码来讲解这个接口:

  • PersonFactoryBean
@Component
public class PersonFactoryBean implements FactoryBean<Person> {
    @Override
    public Person getObject() throws Exception {
        return new Person();
    }

    @Override
    public Class<?> getObjectType() {
        return Person.class;
    }
}
  • BeanFactoryDemo
@SuppressWarnings("all")
public class BeanFactoryDemo {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext applicationContext = ApplicationConfig.getApplicationContext();
        Person person = (Person) applicationContext.getBean("person", "Jack");
        PersonFactoryBean factoryBean = (PersonFactoryBean) applicationContext.getBean("&personFactoryBean");
        Person personB = factoryBean.getObject();
        personB.setName("The Bean Created By FactoryBean");
        System.out.println(personB.toString());
    }
}

对于实现FactoryBean接口的bean,spring在getBean的时候会调用其中的getObject()方法,而不是获取FactoryBean本身。

FactoryBean典型应用

  • mybatis整合到Spring中的xml文件
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="configLocation" value="classpath:config/mybatis-config.xml" />
  <property name="mapperLocations" value="classpath*:config/mappers/**/*.xml" />
</bean>

找到SqlSessionFactoryBean,你会看到它是实现了FactoryBean<SqlSessionFactory>

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

        return this.sqlSessionFactory;
    }

UML

简单聊聊BeanFactory的体系:

  • ListableBeanFactory
  • HierarchicalBeanFactory
  • AutowireCapableBeanFactory
  • ConfigurableBeanFactory
  • ConfigurableListableBeanFactory
  • DefaultListableBeanFactory

总结

Spring的BeanFactory接口定义了一个容器所需要具备的工厂接口,其定制化需求由其扩展子接口进行补充,每个扩展子接口对应不同的职责,最后由ConfigurableListableBeanFactory做统一的汇总,再由DefaultListableBeanFactory统一实现其中的方法,形成内置的IOC容器,但是注意,BeanFactroy还未达成企业应用级别的容器,但是已经具备了容器的基础能力。

举报

相关推荐

0 条评论