BeanFactory还是ApplicationContext及
2018-12-17 本文已影响32人
昨日已逝去
Feature | BeanFactory | ApplicationContext |
---|---|---|
bean实例化/注入 | 支持 | 支持 |
实例生命周期管理 | 不支持 | 支持 |
自动BeanPostProcessor注册 | 不支持 | 支持 |
自动BeanFactoryPostProcessor注册 | 不支持 | 支持 |
方便MessageSource接收 | 不支持 | 支持 |
内置的ApplicationEvent发布机制 | 不支持 | 支持 |
使用BeanFactroy加载时,要手动附加所需的功能。
实例:
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// populate the factory with bean definitions
// now register any needed BeanPostProcessor instances
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
factory.addBeanPostProcessor(new MyBeanPostProcessor());
// now start using the factory
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new FileSystemResource("beans.xml"));
// bring in some property values from a Properties file
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
// now actually do the replacement
cfg.postProcessBeanFactory(factory);
深入源码,探索AppliContext是如何和BeanFactory建立关系
- 1 先从ClassPathXmlApplicationContext走起
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
super(parent);
this.setConfigLocations(configLocations);
if (refresh) {
this.refresh(); //beanFactory的关联函数
}
}
- 2 进入refresh()
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); //此方法是和beanFactory关联,进行xml解析和groovy解析生成bean的函数
this.postProcessBeanFactory(beanFactory);//这里就是postProcessBeanFactory的自动注册,所以beanFactory不具备自动注册功能;注册成功后,后续bean的生命周期中会进行检查并执行相应的方法。
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
...
}
}
- 细看obtainFreshBeanFactory方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
Aware的作用
说到Aware必须要了解bean的生命周期(不了解的直接百度),在bean的生命周期介绍中都会提到5大接口BeanNameAware
,BeanFactoryAware
,ApplicationContextAware
,InitializingBean
,DisposableBean
。
可以看出去BeanNameAware
等都是Aware
的继承;下面我们就分析这些接口的作用。
BeanNameAware
- 实现BeanNameAware的类都会实现一个
setBeanName
方法,而这个方法所给的值就是beanName
;也就是所传递是容器的本身。同理ApplicationContextAware传递的参数是bean自己所在的上下文。
实例
- User
public class User implements BeanNameAware{
private String id;
private String name;
public void setBeanName(String beanName) {
id = beanName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
- User1
public class User1 {
private String id;
private String name;
public void setBeanName(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User1{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
<bean id="user" class="com.zwd.example.test.zzz.User">
</bean>
<bean id="user1" class="com.zwd.example.test.zzz.User1">
</bean>
- Test
public class ApplicationTest {
@Test
public void test1() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("tinyioc.xml");
System.out.println("user: "+applicationContext.getBean("user"));
System.out.println("user1: "+applicationContext.getBean("user1"));
}
}
- 输出
user: User{id='user', name='null'}
user1: User1{id='null', name='null'}