BeanFactory与ApplicationContext
既然
BeanFactory
是spring的顶级接口,那么我们常用的
ApplicationContext
又是什么呢?
首先它们都提供了spring容器的api。但前者是简化版,后者有更多的功能。
从ApplicationContext
的字面意思就可以看到,它适用于不同环境,有xml环境的,有注解环境的,有web环境的。
这是spring官网给出的区别。
可以看到,ApplicationContext
有更多的功能,并且对bean的管理是自动化的。
我们从两个方面检测两个接口的区别。
是否懒加载
我有一个学生bean:
public class Student {
public static boolean isBeanInstantiated = false;
public static boolean isIsBeanInstantiated() {
return isBeanInstantiated;
}
public static void setIsBeanInstantiated(boolean isBeanInstantiated) {
Student.isBeanInstantiated = isBeanInstantiated;
}
public void postConstruct() {
setIsBeanInstantiated(true);
}
}
并且在注册表中配置它的信息以及初始化方法:
<bean id="student" class="com.ocean.testBeanFactoryAndApplicationContext.Bean.Student"
init-method="postConstruct"
/>
也就是说,如果Student
初始化了,那么isBeanInstantiated
就会为true
。
我们知道,bean默认是单例的,是在容器(ApplicationContext
)初始化阶段就被初始化的,所以我们初始化好容器就可以拿到bean:
@Test
public void testLazyAndEagerWithApplicationContext() {
ClassPathXmlApplicationContext applicationContext
= new ClassPathXmlApplicationContext("factory-example.xml");
System.out.println("isIsBeanInstantiated? : " + Student.isIsBeanInstantiated());
System.out.println(applicationContext.getBean("student"));
}
结果:
isIsBeanInstantiated? : true
com.ocean.testBeanFactoryAndApplicationContext.Bean.Student@75412c2f
另一方面,BeanFactory
只有在你getBean的时候才会去初始化bean。
@Test
public void testLazyAndEagerWithBeanFacory() {
ClassPathResource classPathResource = new ClassPathResource("factory-example.xml");
XmlBeanFactory factory = new XmlBeanFactory(classPathResource);
System.out.println("isIsBeanInstantiated? : " + Student.isIsBeanInstantiated());
factory.getBean("student");
System.out.println("After getBean().......");
System.out.println("isIsBeanInstantiated? : " + Student.isIsBeanInstantiated());
}
isIsBeanInstantiated? : false
After getBean().......
isIsBeanInstantiated? : true
是否自动注册后置处理器
我们写一个自定义的BeanPostProcessor
:
public class MyBeanPostProcessor implements BeanPostProcessor {
private static boolean isMyBeanPostProcessorRegistered = false;
public static void setIsMyBeanPostProcessorRegistered(boolean newValue) {
MyBeanPostProcessor.isMyBeanPostProcessorRegistered = newValue;
}
public static boolean isMyBeanPostProcessorRegistered() {
return isMyBeanPostProcessorRegistered;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
setIsMyBeanPostProcessorRegistered(true);
return null;
}
}
并且写一个BeanFactoryPostProcessor
:
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
private static boolean isBeanFactoryProcessorRegistered = false;
public static void setIsBeanFactoryProcessor(boolean newValue) {
MyBeanFactoryPostProcessor.isBeanFactoryProcessorRegistered = newValue;
}
public static boolean isBeanFactoryProcessorRegistered() {
return isBeanFactoryProcessorRegistered;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
setIsBeanFactoryProcessor(true);
}
}
并在注册表中注册它们:
<bean id="myBeanPostProcessor"
class=
"com.ocean.testBeanFactoryAndApplicationContext.postprocessors.MyBeanPostProcessor">
</bean>
<bean id="myBeanFactoryPostProcessor" class=
"com.ocean.testBeanFactoryAndApplicationContext.postprocessors.MyBeanFactoryPostProcessor">
</bean>
ApplicationContext会自动注册它们:
@Test
public void testBeanPostProcessorRegistrationWithApplicationContext(){
ClassPathXmlApplicationContext applicationContext
= new ClassPathXmlApplicationContext("factory-example.xml");
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
AbstractBeanFactory abstractBeanFactory = (AbstractBeanFactory) beanFactory;
abstractBeanFactory.getBeanPostProcessors().stream().forEach(System.out::println);
}
好。
现在我们来看BeanFactory
的表现。
@Test
public void testBeanFactoryWithPostProcessor() {
Resource res = new ClassPathResource("factory-example.xml");
ConfigurableListableBeanFactory factory = new XmlBeanFactory(res);
System.out.println(MyBeanFactoryPostProcessor.isBeanFactoryProcessorRegistered());
System.out.println(MyBeanPostProcessor.isMyBeanPostProcessorRegistered());
}
结果:
false
false
我们只能通过手动注册:
@Test
public void testBeanFactoryWithPostProcessor() {
Resource res = new ClassPathResource("factory-example.xml");
ConfigurableListableBeanFactory factory = new XmlBeanFactory(res);
MyBeanFactoryPostProcessor myBeanFactoryPostProcessor = new MyBeanFactoryPostProcessor();
myBeanFactoryPostProcessor.postProcessBeanFactory(factory);
System.out.println(myBeanFactoryPostProcessor.isBeanFactoryProcessorRegistered());
MyBeanPostProcessor myBeanPostProcessor = new MyBeanPostProcessor();
factory.addBeanPostProcessor(myBeanPostProcessor);
Student student = (Student) factory.getBean("student");
System.out.println(myBeanPostProcessor.isMyBeanPostProcessorRegistered());
}