BeanFactory
BeanFactory和ApplicationContext是Spring中的两种容器。
BeanFactory默认采用延迟初始化策略,所以相对来说,容器启动较快,所需资源不多。
ApplicationContext间接继承自BeanFactory,增加国际化等高级功能,其管理的对象在容器启动后默认全部初始化完成,所以启动所需要资源较多,所需时间长
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
// 返回bean
Object getBean(String var1) throws BeansException;
<T> T getBean(String var1, Class<T> var2) throws BeansException;
Object getBean(String var1, Object... var2) throws BeansException;
<T> T getBean(Class<T> var1) throws BeansException;
<T> T getBean(Class<T> var1, Object... var2) throws BeansException;
boolean containsBean(String var1);
// 是否是单例bean
boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
// 是否是原型bean
boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;
// bean的类
Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
// bean的别名,XML种的id
String[] getAliases(String var1);
}
在BeanFactory接口中,如果你熟悉Spring的配置文件的话,想必会看到很多熟悉的方法。
实际上,BeanFactory只负责定义如何访问查看容器内Bean的状态,那么Bean从哪里来的呢?这些比较复杂的问题就交给底下人去办好啦,DefaultListableBeanFactory是BeanFactory的一个间接子类,它实现了BeanFactory的一个子接口。同时,他还实现了BeanDefinitionRegistry,这个接口定义了Bean的注册逻辑。
这里首先要知道Bean在容器中的形式是BeanDefinition,BeanDefinition实例中包括了对象的所有信息,当被注入类向容器请求依赖对象时候,BeanFactory就会通过对应BeanDefinition中的信息返回一个实例。
可以把BeanFactory看成是图书馆,BeanDefinitionRegistry就是图书馆里边的书架,书就在书架上存放着,这里也就要求我们的图书馆只能有一个书架。每个BeanDefinition都要被放在BeanDefinitionRegistry中才能被容器管理。
至于BeanDefinition,一般是通过BeanDefinitionReader读取配置文件并映射成对应的BeanDefinition来生成的。
FactoryBean
FactoryBean其实就是个工厂Bean接口,本质上也还是个bean,它生成的以及提供给容器管理的正是它的getObject()方法所返回的bean
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
// 返回要生产的bean
T getObject() throws Exception;
// 返回生产的bean的Class
Class<?> getObjectType();
// 返回生产的bean是否是Singleton
default boolean isSingleton() {
return true;
}
}
来看一下FactoryBean的使用
public class User implements FactoryBean {
private int id;
private String name;
@Override
public boolean isSingleton() {
return false;
}
@Override
public Object getObject() throws Exception {
return new User(1,"fbb");
}
@Override
public Class<?> getObjectType() {
return User.class;
}
// setter // getter // constructor
}
上边这个User实现FactoryBean,可以用来生产名字为 fbb 的user,接着把这个工厂Bean交给Spring管理
@Configuration
public class config {
@Bean
public User user(){
return new User(100,"bbf");
}
}
可以看到我们在容器中注册了名字为 bbf 的user
接着检验一下到底容器中最后提供的user的名字是什么
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringdemoApplication.class)
public class UserTest {
@Autowired
private User user;
@Test
public void tt(){
System.out.println(user.getName());
}
}
fbb
最后可以看到,容器提供的user的名字其实还是fbb,即我们的工厂bean中提供的,因为我们从工厂方法中获得的bean一定是从getObject()这个方法中获得的~
总结
所以,我们大体上应该明白了,BeanFactory是容器,而FactoryBean则是工厂Bean,帮助我们定制实例化Bean,其实这何尝不是代理模式的一个应用,我们可以在getObject()那里再加一些别的逻辑,相当于搞了一层代理~