顶层容器接口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
还未达成企业应用级别的容器,但是已经具备了容器的基础能力。