BeanFactory与ApplicationContext

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());
	}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值