一、ApplicationContext
ApplicationContext是spring继BeanFactory之外的另一个核心接口或容器,允许容器通过应用程序上下文环境创建、获取、管理bean。
在Spring 中, BeanFactory 接口的各种实现负责bean实例化,为Spring 管理的bean提供依赖注入和生命周期支持。然而,作为BeanFactory接口的扩展, ApplicationContext 还提供其他有用的功能。ApplicationContext 的主要功能是提供一个更丰富的框架来构建应用程序。ApplicationContext 更加了解所配置的bean(与BeanFactory 相比), 在使用Spring 基础结构类和接口(例BeanFactoryPostProcessor) 的情况下,ApplicationContext 可以代替你与这些类或接口进行交互, 从而减少为了使用Spring 所需编写的代码量。
使用ApplicationContext 的最大好处是,它允许以完全声明的方式配置和管理Spring 以及Spring 所管理的资源。这意味着Spring 尽可能提供支持类来自动将ApplicationContext 加载到应用程序中,从而不需要编写任何代码来访问ApplicationContext。
二:常见的ApplicationContext
spring为ApplicationContext提供了很多实现类,其中有四个比较常用的: ClassPathXmlApplicationContext 通过读取工程src目录下的配置文件启动ioc容器
ApplicationContext ctx = new ClassPathXmlApplicationContext( "applicationContext.xml ");
FileSystemXmlApplicationContext 通过读取系统文件路径下的配置文件启动ioc容器
ApplicationContext context = new FileSystemXmlApplicationContext( "D:/test/applicationContext.xml ");
AnnotationConfigWebApplicationConetxt 通过配置类的方式启动ioc容器
uml如图:  三、ioc容器的初始化 可以看到以上ApplicationContex都有个父类是AbstractApplicationContext,refresh()方法是该父类的方法,在ioc容器的启动过程中都会走调用refresh()方法,refresh 函数中包含了几乎ApplicationContext 中提供的全部功能,而且此函数中逻辑非常清晰明了, 使我们很容易分析对应的层次及逻辑:
public void refresh() throws BeansException , IllegalStateException {
synchronized (this. startupShutdownMonitor) {
prepareRefresh() ;
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory() ;
prepareBeanFactory(beanFactory) ;
try {
postProcessBeanFactory(beanFactory) ;
invokeBeanFactoryPostProcessors(beanFactory) ;
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
finishBeanFactoryinitialization(beanFactory);
finishRefresh() ;
catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex) ,
throw ex;
}
}
1、AbstractApplicationContext#prepareRefresh()
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
initPropertySources();
getEnvironment().validateRequiredProperties();
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
this.earlyApplicationEvents = new LinkedHashSet<>();
2、AbstractApplicationContext#obtainFreshBeanFactory()
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
DefaultListableBeanFactory BeanFactory创建方式为:
BeanFactory bf= new XmlBeanFactory("beanFactoryTest.xml")
其中的XmlBeanFactory 继承自DefaultListableBeanFactory,并提供了XmlBeanDefinitionReader 类型的reader 属性, 也就是说DefaultListableBeanFactory是容器的基础。必须首先要实例化,那么在这里就是实例化DefaultListableBeanFactory的步骤。
2.1、destroyBeans()
private boolean singletonsCurrentlyInDestruction = false;
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
public void destroySingletons() {
if (logger.isDebugEnabled()) {
logger.debug("Destroying singletons in " + this);
}
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
clearSingletonCache();
}
可以看到destroy其实就是去清空容器中的缓存。
2.2、customizeBeanFactory 定制beanFactory
这里已经开始了对BeanFactory 的扩展,在基本容器的基础上,增加了是否允许覆盖是否允许扩展的设置并提供了注解@Qualifier 和@Autowired 的支持。
protected void customizeBeanFactory (DefaultListableBeanFactory beanFactory ) {
if (this.allowBeanDefinitionOverriding 1= null ) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding) ;
}
if (this.allowCircularReferences != null ) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences );
beanFactory .setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
}
敲重点:是否允许bean的循环依赖配置在这里。 allowBeanDefinitionOverroding的配置可以覆盖相同名称的bean,这个配置要慎重开启。
3、prepareBeanFactory(beanFactory)
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartup.class);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
if (!IN_NATIVE_IMAGE && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
ResourceEditorRegistrar 类的 registerCustomEditors方法注册了一系列的常用类型的属性编辑器 如:doRegisterEditor(registry,Class.class, new ClassEditor(classLoader))实现的功能就是注册 Class类对应的属件编辑器。那么,注册后,一旦某个实体bean中存在一些Class类型的属性, 那么Spring会调用ClassEditor将配置中定义的String类型转换为Class类型并进行陚值。通过这种方式我们可以去实现自己的属性编辑器。
3.2 、beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
bean instanceof ApplicationStartupAware)) {
return bean;
}
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationStartupAware) {
((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
ApplicationContextAwareProcessor主要作用就是在beanFactory bean初始化的时候调用各个Aware接口。
未完待续。。。。。。。。
|