* BeanFactory:获取bean,判断bean是否存在,获取别名,scope确定等接口;
* ListableBeanFactory:可以根据类型、注解批量获取bean,获取bean定义相关数据;
* HierarchicalBeanFactory:分层bean,获取父beanFactory;
* SimpleJndiBeanFactory:通过jndi配置获取;
* AutowireCapableBeanFactory:实现自动装配的功能,提供了创建bean,销毁bean等操作;
@Test
public void test2(){
BeanFactory beanFactory=new XmlBeanFactory(new ClassPathResource("application.xml"));
HelloService helloService=beanFactory.getBean("helloService", HelloService.class);
System.out.println(helloService.hello("mixi"));
}
采用配置文件形式(classPathxml)。ApplicationContext继承 EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver接口,不仅实现了bean获取、分层bean的接口,还扩展了spring环境(配置参数、profile)、国际化支持(MessageSource),事件触发(bean创建事件、刷新事件等)、获取资源(资源可能为classPath,或者systemPath等等)。
@Test
public void test(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("classpath:application.xml");
System.out.println(applicationContext.getApplicationName());
HelloService helloService=applicationContext.getBean("helloService", HelloService.class);
System.out.println(helloService.hello("mixi"));
}
配置文件如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="helloService" class="com.mixi.spring.demo.ioc.service.impl.HelloServiceImpl">bean>
beans>
ClassPathXmlApplicationContext是从classpath xml配置文件下获取,其他的包括FileSystemXmlApplicationContext(从文件系统获取xml配置),XmlServletWebServerApplicationContext(从web应用的根目录读取配置文件,需要先在web.xml中配置),AnnotationConfigServletWebServerApplicationContext(通过注解方式获取配置),ReactiveWebServerApplicationContext(响应式的web配置),AnnotationConfigReactiveWebServerApplicationContext(通过配置响应式配置),AnnotationConfigWebApplicationContext(注解形式),GroovyWebApplicationContext(groovy配置)
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
//设置父级applicationContext
super(parent);
//设置配置目录
setConfigLocations(configLocations);
if (refresh) {
//重点在刷新着,此方法可以手动调用,自己刷新
refresh();
}
}
public void refresh() throws BeansException, IllegalStateException {
//同步块
synchronized (this.startupShutdownMonitor) {
//准备刷新,记录启动时间,配置文件重新初始化,applicationListener重新初始化
prepareRefresh();
// beanFactory刷新及获取,BeanDefinition 初始化,但未初始化bean
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
prepareBeanFactory(beanFactory);
try {
// 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
// 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】
// 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化,可修改配置BeanDefinition
// 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
postProcessBeanFactory(beanFactory);
// 执行postProcess beanFactory
invokeBeanFactoryPostProcessors(beanFactory);
//注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
registerBeanPostProcessors(beanFactory);
//初始化国际化
initMessageSource();
//初始化事件广播器
initApplicationEventMulticaster();
// 从方法名就可以知道,典型的模板方法(钩子方法),
// 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
onRefresh();
// 注册事件监听器,监听器需要实现 ApplicationListener 接口
registerListeners();
// 初始化所有的 singleton beans
//(lazy-init 的除外)
finishBeanFactoryInitialization(beanFactory);
// 最后,广播事件,ApplicationContext 初始化完成
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
//异常结束,需要销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
destroyBeans();
//刷新失败
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// 清缓存
resetCommonCaches();
}
}
}
创建beanFactory过程中,将初始化bean定义。源码如下
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {//是否已经初始化了beanFactory,已经初始化了需要销毁bean,同时关闭BeanFactory
destroyBeans();
closeBeanFactory();
}
try {
//创建BeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//设置序列化ID
beanFactory.setSerializationId(getId());
//自定义Factory,配置是否能够bean覆盖和循环应用
customizeBeanFactory(beanFactory);
//加载bean定义
loadBeanDefinitions(beanFactory);
//互斥设置
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
加载bean定义过程,即loadBeanDefinitions(),先查看BeanDefinition,此类定义了bean加载的信息。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// 我们可以看到,默认只提供 sington 和 prototype 两种,
// 很多读者都知道还有 request, session, globalSession, application, websocket 这几种,
// 不过,它们属于基于 web 的扩展。
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
// 比较不重要,直接跳过吧
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
// 设置父 Bean,这里涉及到 bean 继承,不是 java 继承。请参见附录介绍
void setParentName(String parentName);
// 获取父 Bean
String getParentName();
// 设置 Bean 的类名称
void setBeanClassName(String beanClassName);
// 获取 Bean 的类名称
String getBeanClassName();
// 设置 bean 的 scope
void setScope(String scope);
String getScope();
// 设置是否懒加载
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
// 设置该 Bean 依赖的所有的 Bean,注意,这里的依赖不是指属性依赖(如 @Autowire 标记的),
// 是 depends-on="" 属性设置的值。
void setDependsOn(String... dependsOn);
// 返回该 Bean 的所有依赖
String[] getDependsOn();
// 设置该 Bean 是否可以注入到其他 Bean 中,只对根据类型注入有效,
// 如果根据名称注入,即使这边设置了 false,也是可以的
void setAutowireCandidate(boolean autowireCandidate);
// 该 Bean 是否可以注入到其他 Bean 中
boolean isAutowireCandidate();
// 主要的。同一接口的多个实现,如果不指定名字的话,Spring 会优先选择设置 primary 为 true 的 bean
void setPrimary(boolean primary);
// 是否是 primary 的
boolean isPrimary();
// 如果该 Bean 采用工厂方法生成,指定工厂名称。对工厂不熟悉的读者,请参加附录
void setFactoryBeanName(String factoryBeanName);
// 获取工厂名称
String getFactoryBeanName();
// 指定工厂类中的 工厂方法名称
void setFactoryMethodName(String factoryMethodName);
// 获取工厂类中的 工厂方法名称
String getFactoryMethodName();
// 构造器参数
ConstructorArgumentValues getConstructorArgumentValues();
// Bean 中的属性值,后面给 bean 注入属性值的时候会说到
MutablePropertyValues getPropertyValues();
// 是否 singleton
boolean isSingleton();
// 是否 prototype
boolean isPrototype();
// 如果这个 Bean 原生是抽象类,那么不能实例化
boolean isAbstract();
int getRole();
String getDescription();
String getResourceDescription();
BeanDefinition getOriginatingBeanDefinition();
}