/**
* 这个类被ContextLoaderListener调用真正执行根应用上下文初始化工作
*
* 在web.xml中通过context-param的配置参数contextClass指定上下文类型,如果没有配置则使用默认值XmlWebApplicationContext
* 使用默认的ContextLoader实现类,任何上下文类都必须实现ConfigurableWebApplicationContext接口
* 处理context-param配置参数 contextConfigLocation,解析成可以通过任何数量潜在可以通过逗号和空格分割的多个文件,例如
* WEB-INF/applicationContext1.xml,WEB-INF/applicationContext2.xml,将该值传递给上下文实例。如果没有特别指出配置,
* 上线文实现类支持使用默认路径 /WEB-INF/applicationContext.xml
* 注意: 如果使用默认的应用上下文实现类,在多配置文件的场景中,后面的Bean定义将会覆盖在之前已经被加载的文件中定义的Bean
*/
public class ContextLoader {
/**
* 根WebApplicationContext实现类的配置参数
*/
public static final String CONTEXT_CLASS_PARAM = "contextClass";
/**
* 根WebApplicationContext 的ID
*/
public static final String CONTEXT_ID_PARAM = "contextId";
/**
* 初始化应用上下文使用的ApplicationContextInitializer类的配置参数
*/
public static final String CONTEXT_INITIALIZER_CLASSES_PARAM = "contextInitializerClasses";
/**
* 配置文件路径
*/
public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector";
public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey";
private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties";
private static final Properties defaultStrategies;
static {
try {//在初始化阶段从classpath中加载默认配置
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
}
}
// ClassLoader和WebApplicationContext的映射表
private static final Map<ClassLoader, WebApplicationContext> currentContextPerThread =
new ConcurrentHashMap<ClassLoader, WebApplicationContext>(1);
private static volatile WebApplicationContext currentContext;
private WebApplicationContext context;
private BeanFactoryReference parentContextRef;
public ContextLoader() {
}
public ContextLoader(WebApplicationContext context) {
this.context = context;
}
/**
* 对给定的Servlet上下文进行Spring WEB应用上下文进行初始化
*/
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
throw new IllegalStateException(
"Cannot initialize context because there is already a root application context present - " +
"check whether you have multiple ContextLoader* definitions in your web.xml!");
}
Log logger = LogFactory.getLog(ContextLoader.class);
servletContext.log("Initializing Spring root WebApplicationContext");
if (logger.isInfoEnabled()) {
logger.info("Root WebApplicationContext: initialization started");
}
long startTime = System.currentTimeMillis();
try {
// 如果当前应用上下文实例为null则创建一个应用上下文
if (this.context == null) {
this.context = createWebApplicationContext(servletContext);
}
// 如果当前的应用上下文对象是 ConfigurableWebApplicationContext
if (this.context instanceof ConfigurableWebApplicationContext) {
//强制类型转换
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
// 如果应用上下文没有生效
if (!cwac.isActive()) {
// 如果该上下文对象为null
if (cwac.getParent() == null) {
//加载父上下文
ApplicationContext parent = loadParentContext(servletContext);
// 设置父上下文
cwac.setParent(parent);
}
configureAndRefreshWebApplicationContext(cwac, servletContext);
}
}
//将该上下文对象放入servlet上下文参数中
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
//获取当前线程的类加载器
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
// 如果ContextLoader的类加载器和当前线程的类加载器一样,则应用上下文对象赋值给currentContext
if (ccl == ContextLoader.class.getClassLoader()) {
currentContext = this.context;
}
else if (ccl != null) {
currentContextPerThread.put(ccl, this.context);
}
if (logger.isDebugEnabled()) {
logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
}
if (logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
}
// 返回应用上下文对象
return this.context;
}
catch (RuntimeException ex) {
logger.error("Context initialization failed", ex);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
throw ex;
}
catch (Error err) {
logger.error("Context initialization failed", err);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
throw err;
}
}
/**
*为当前ContextLoader实例化 WebApplicationContext
*/
protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
//获取上下文类
Class<?> contextClass = determineContextClass(sc);
//如果该上下文类没有实现ConfigurableWebApplicationContext接口则抛出异常
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
}
// 返回该上下文类的实例
return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
}
@Deprecated
protected WebApplicationContext createWebApplicationContext(ServletContext sc, ApplicationContext parent) {
return createWebApplicationContext(sc);
}
/**
* 配置同时刷新WebApplicationContext
**/
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
// 如果应用上下文的Id还是原始值
if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
//获取配置参数contextId,如果配置参数不为空则将其设置为应用上下文ID
String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);
if (idParam != null) {
wac.setId(idParam);
}
else {
if (sc.getMajorVersion() == 2 && sc.getMinorVersion() < 5) {
// Servlet <= 2.4: resort to name specified in web.xml, if any.
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
ObjectUtils.getDisplayString(sc.getServletContextName()));
}
else {
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
ObjectUtils.getDisplayString(sc.getContextPath()));
}
}
}
//设置Servlet上下文对象
wac.setServletContext(sc);
//获取配置参数contextConfigLocation路径
String initParameter = sc.getInitParameter(CONFIG_LOCATION_PARAM);
if (initParameter != null) {
wac.setConfigLocation(initParameter);
}
customizeContext(sc, wac);
//刷新用上下文
wac.refresh();
}
/**
* 返回上下文类型
*/
protected Class<?> determineContextClass(ServletContext servletContext) {
//从servlet上下文中获取初始化配置参数contextClass的值
String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
// 如果contextClassName不为null则放回配置的Class对象
if (contextClassName != null) {
try {
return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException(
"Failed to load custom context class [" + contextClassName + "]", ex);
}
}
else {
// 如果没有配置则使用XmlWebApplicationContext
contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
try {
return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException(
"Failed to load default context class [" + contextClassName + "]", ex);
}
}
}
/**
* 获取所有配置的contextInitializerClasses
*/
@SuppressWarnings("unchecked")
protected List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>>
determineContextInitializerClasses(ServletContext servletContext) {
String classNames = servletContext.getInitParameter(CONTEXT_INITIALIZER_CLASSES_PARAM);
List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> classes =
new ArrayList<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>>();
if (classNames != null) {
for (String className : StringUtils.tokenizeToStringArray(classNames, ",")) {
try {
Class<?> clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
Assert.isAssignable(ApplicationContextInitializer.class, clazz,
"class [" + className + "] must implement ApplicationContextInitializer");
classes.add((Class<ApplicationContextInitializer<ConfigurableApplicationContext>>)clazz);
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException(
"Failed to load context initializer class [" + className + "]", ex);
}
}
}
return classes;
}
/**
*在设置配置路径后单在刷新应用上下文前自定义应用上下文
*/
protected void customizeContext(ServletContext servletContext, ConfigurableWebApplicationContext applicationContext) {
// 从servlet上下文中获取配置的ApplicationContextInitializer
List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> initializerClasses =
determineContextInitializerClasses(servletContext);
//配置的ApplicationContextInitializer对象为空则直接返回
if (initializerClasses.size() == 0) {
return;
}
// 获取应用上线文类对象
Class<?> contextClass = applicationContext.getClass();
ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerInstances =
new ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>>();
//遍历应用所有ApplicationContextInitializer
for (Class<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerClass : initializerClasses) {
Class<?> initializerContextClass =
GenericTypeResolver.resolveTypeArgument(initializerClass, ApplicationContextInitializer.class);
Assert.isAssignable(initializerContextClass, contextClass, String.format(
"Could not add context initializer [%s] as its generic parameter [%s] " +
"is not assignable from the type of application context used by this " +
"context loader [%s]: ", initializerClass.getName(), initializerContextClass.getName(),
contextClass.getName()));
initializerInstances.add(BeanUtils.instantiateClass(initializerClass));
}
applicationContext.getEnvironment().initPropertySources(servletContext, null);
//排序
Collections.sort(initializerInstances, new AnnotationAwareOrderComparator());
// 执行所有初始化
for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : initializerInstances) {
initializer.initialize(applicationContext);
}
}
protected ApplicationContext loadParentContext(ServletContext servletContext) {
ApplicationContext parentContext = null;
String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);
String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);
if (parentContextKey != null) {
// locatorFactorySelector may be null, indicating the default "classpath*:beanRefContext.xml"
BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
Log logger = LogFactory.getLog(ContextLoader.class);
if (logger.isDebugEnabled()) {
logger.debug("Getting parent context definition: using parent context key of '" +
parentContextKey + "' with BeanFactoryLocator");
}
this.parentContextRef = locator.useBeanFactory(parentContextKey);
parentContext = (ApplicationContext) this.parentContextRef.getFactory();
}
return parentContext;
}
public void closeWebApplicationContext(ServletContext servletContext) {
servletContext.log("Closing Spring root WebApplicationContext");
try {
if (this.context instanceof ConfigurableWebApplicationContext) {
((ConfigurableWebApplicationContext) this.context).close();
}
}
finally {
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if (ccl == ContextLoader.class.getClassLoader()) {
currentContext = null;
}
else if (ccl != null) {
currentContextPerThread.remove(ccl);
}
servletContext.removeAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (this.parentContextRef != null) {
this.parentContextRef.release();
}
}
}
/**
*获取当前ClassLoader对应的应用上下文
**/
public static WebApplicationContext getCurrentWebApplicationContext() {
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if (ccl != null) {
WebApplicationContext ccpt = currentContextPerThread.get(ccl);
if (ccpt != null) {
return ccpt;
}
}
return currentContext;
}
}
通过XmlWebApplicationContext可以发现这个类的继承体系如下图所示:
实现了相当多的接口,我们首先从BeanFactory看起。
BeanFactory是一个访问Spring容器的根节点,是一个Bean容器的最基本功能的定义
public interface BeanFactory {
/**
*用来访问BeanFactory本身的bean名称的前缀
*/
String FACTORY_BEAN_PREFIX = "&";
/**
*返回指定名称的Bean实例
*/
Object getBean(String name) throws BeansException;
/**
*返回指定名称和类型的Bean实例
*/
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
/**
* 返回指定类型的Bean实例
*/
<T> T getBean(Class<T> requiredType) throws BeansException;
/**
*可变参数主要用来指定是否显示使用静态工厂方法创建一个原型(prototype)Bean。
*/
Object getBean(String name, Object... args) throws BeansException;
/**
*判断BeanFactory中是否包含指定名称的Bean
*/
boolean containsBean(String name);
/**
*判断指定名称的Bean是否是单例模式的Bean
*/
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
/**
*判断指定名称的Bean是否是原型类型的Bean
*/
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
/**
* 判断指定名称的Bean的类型和指定的类型是否匹配
*/
boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
/**
* 返回指定名称的Bean的类型
*/
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
/**
* 获取指定名称的Bean的所有别名
*/
String[] getAliases(String name);
}
HierarchicalBeanFactory是的BeanFactory具有了层次结构,具备了管理双亲IOC容器的功能
public interface HierarchicalBeanFactory extends BeanFactory {
/**
* 返回上一级BeanFatory,如果没有则返回null
*/
BeanFactory getParentBeanFactory();
/**
* 返回本地BeanFactory中是否包含指定Bean名称的Bean,忽略在上一级BeanFactory中的bean
*/
boolean containsLocalBean(String name);
}
LisableBeanFactory接口继承了BeanFactory接口,一次预加载所有的bean配置
public interface ListableBeanFactory extends BeanFactory {
/**
* 判断是否包含指定名称的bean的配置
*/
boolean containsBeanDefinition(String beanName);
/**
*获取容器中bean的数量
*/
int getBeanDefinitionCount();
/**
* 获取所有Bean的名称
*/
String[] getBeanDefinitionNames();
/**
*获取所有指定类型的bean的名称
*/
String[] getBeanNamesForType(Class<?> type);
/**
* 获取所有指定类型的bean的名称
*/
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
/**
* 获取所有指定类型的Bean的映射,
*/
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
/**
*查找所有具有指定注解类型的注解的bean
*/
<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
/**
* 查找所有具有指定注解类型的注解的bean
*/
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
throws BeansException;
/**
* 查找指定Bean上指定注解类型的注解
*/
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);
}
ApplicationEventPublisher 分装了一个发布ApplicationEvent的功能
public interface ApplicationEventPublisher {
/**
* 通知这个应用注册的所有监听器
*/
void publishEvent(ApplicationEvent event);
}
MessageSource消息参数化和国际化支持接口
public interface MessageSource {
String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}
ApplicationContext
/**
* 为应用提供配置的核心接口。在应用运行期间只读。
* ApplicationContext提供了如下功能:
* 访问应用组件的BeanFactory方法,继承自ListableBeanFactory
* 使用通用方式加载文件资源的能力,继承自ResourceLoader
* 向注册的监听器发布事件的能力,继承自ApplicaitonEventPublisher
* 支持消息国际化的能力,继承自MessageSource
* 继承父上下文。子上下文定义优先于祖先上下文。
*/
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
/**
*返回这个应用上下文的唯一Id,如果没有则返回null
*/
String getId();
/**
*获取应用上下文显示的名称
*/
String getDisplayName();
/**
* 返回应用上下文第一次加载的时间毫秒值
*/
long getStartupDate();
/**
* 获取父上下文,如果没有则返回null
*/
ApplicationContext getParent();
/**
*返回AutoCapableBeanFactory,为这个上下文提供AutowireCapableBeanFactory功能
*/
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
ConfigurableApplicationContext接口,通过上面是ContextLoader可以发现refresh()方法是定义在该接口中的,在这里也就明白为什么要求WebApplicationContext对象必须实现这个接口了。
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle {
/**
* 上下文配置路径的分割符
*/
String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
/**
* ConversionService bean的名称
*/
String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
/**
* LoadTimeWeaver Bean的名称
*
*/
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
/**
* 环境变量Bean的名称
*/
String ENVIRONMENT_BEAN_NAME = "environment";
/**
* 系统属性Bean的名称
*/
String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
/**
* 系统环境变量Bean的名称
*/
String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
/**
* 设置应用上下文唯一Id
*/
void setId(String id);
/**
* 设置父山下文
*/
void setParent(ApplicationContext parent);
/**
* 获取环境变量
*/
ConfigurableEnvironment getEnvironment();
/**
* 设置环境变量
*/
void setEnvironment(ConfigurableEnvironment environment);
/**
* 注册一个BeanFactoryPostProcessor
*/
void addBeanFactoryPostProcessor(BeanFactoryPostProcessor beanFactoryPostProcessor);
/**
* 注册一个ApplicationEvent监听器
*/
void addApplicationListener(ApplicationListener<?> listener);
/**
*刷新应用上下文
*/
void refresh() throws BeansException, IllegalStateException;
/**
* 注册一个JVM关闭的钩子,在关闭JVM时关闭应用上下文
*/
void registerShutdownHook();
/**
* 关闭应用上下文
*/
void close();
/**
* 判断应用上下文是否处于激活状态
*/
boolean isActive();
/**
* 返回次上下文内部BeanFactory
*/
ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}
ApplicationContext容器自身有一个初始化和销毁的过程。对于启动过程是在AbstractApplicationContext中实现的。
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext, DisposableBean {
/**
* MessageSource bean的名称
*/
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
/**
* LifecycleProcessor bean的名称
*/
public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
static {
ContextClosedEvent.class.getName();
}
/** Logger used by this class. Available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
/** 当前应用上下文唯一ID*/
private String id = ObjectUtils.identityToString(this);
/**显示名称 */
private String displayName = ObjectUtils.identityToString(this);
/**父上下文 */
private ApplicationContext parent;
/** BeanFactoryPostProcessors */
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors =
new ArrayList<BeanFactoryPostProcessor>();
/** 应用上下文启动时间*/
private long startupDate;
/** 标志上下文对象是否是激活状态*/
private boolean active = false;
/**标识该上下文对象是否是已经关闭状态 */
private boolean closed = false;
/** 同步监视器对象*/
private final Object activeMonitor = new Object();
/**应用上下文刷新或销毁的同步监视器*/
private final Object startupShutdownMonitor = new Object();
private Thread shutdownHook;
private ResourcePatternResolver resourcePatternResolver;
private LifecycleProcessor lifecycleProcessor;
private MessageSource messageSource;
private ApplicationEventMulticaster applicationEventMulticaster;
private Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>();
private ConfigurableEnvironment environment;
public AbstractApplicationContext() {
this(null);
}
public AbstractApplicationContext(ApplicationContext parent) {
this.parent = parent;
this.resourcePatternResolver = getResourcePatternResolver();
this.environment = createEnvironment();
}
/**
* 获取自动装配BeanFactory
**/
public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
return getBeanFactory();
}
/**
*向所有监听器发布制定的事件
*/
public void publishEvent(ApplicationEvent event) {
Assert.notNull(event, "Event must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Publishing event in " + getDisplayName() + ": " + event);
}
getApplicationEventMulticaster().multicastEvent(event);
if (this.parent != null) {
this.parent.publishEvent(event);
}
}
// ApplicationContext启动过程
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备刷新应用上下文
prepareRefresh();
// 告诉子类上下文内部BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备应用上下文的BeanFactory
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//允许上下文的子类后置处理
postProcessBeanFactory(beanFactory);
//调用上下文中注册的BeanFactory后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 注册Bean的后置处理器.
registerBeanPostProcessors(beanFactory);
// 初始化消息
initMessageSource();
//初始化ApplicationEventMulticaster
initApplicationEventMulticaster();
// 子类的初始化具体处理
onRefresh();
// 注册监听器
registerListeners();
// 实例化剩余所有非懒加载的单例实例
finishBeanFactoryInitialization(beanFactory);
// 发送响应的事件
finishRefresh();
}
catch (BeansException ex) {
//销毁Bean
destroyBeans();
// 重置active标识
cancelRefresh(ex);
//将异常传播给调用者
throw ex;
}
}
}
/**
* 准备当前应用上下文的刷新,设置启动时间,激活标识,执行占位符的初始化
*/
protected void prepareRefresh() {
// 设置启动时间为当前时间
this.startupDate = System.currentTimeMillis();
//设置激活标识
synchronized (this.activeMonitor) {
this.active = true;
}
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// 初始化占位符
initPropertySources();
getEnvironment().validateRequiredProperties();
}
protected void initPropertySources() {
}
/**
* 告诉子类刷新内部BeanFactory,调用子类的refreshBeanFactory完成其内部factory的启动
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
/**
* 配置Bean工厂的标准特性,比如上下文的类加载器,后置处理器等
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//设置classLoader
beanFactory.setBeanClassLoader(getClassLoader());
//设置BeanExpressionResolver
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
//设置PropertyEditor
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//设置BeanPostProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
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());
}
}
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
/**
* 实例化同时调用所有注册的BeanFactoryPostProcessor
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
Set<String> processedBeans = new HashSet<String>();
if (beanFactory instanceof BeanDefinitionRegistry) {
// 强制类型转换
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
new LinkedList<BeanDefinitionRegistryPostProcessor>();
//遍历beanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
OrderComparator.sort(registryPostProcessorBeans);
for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
processedBeans.addAll(beanMap.keySet());
}
else {
invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
}
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
//调用实现优先级接口的BeanFactoryPostProcessor
OrderComparator.sort(priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
//第二步,调用实现Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
OrderComparator.sort(orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
//最后调用其他所有的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
}
/**
*调用给定的BeanFactoryPostProcessor
*/
private void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//从beanFactory中获取所有BeanPostProcessor名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
//遍历所有postProcessorNames
for (String ppName : postProcessorNames) {
// 如果BeanProcessor实现了PriorityOrdered接口则保存到priorityOrderedPostProcessor
if (isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 排序
OrderComparator.sort(priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
OrderComparator.sort(orderedPostProcessors);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
OrderComparator.sort(internalPostProcessors);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector());
}
private void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 如果当前BeanFactory中包含messageSource
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
//将messageSource对象赋值给messageSource
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this.messageSource + "]");
}
}
}
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isDebugEnabled()) {
logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate LifecycleProcessor with name '" +
LIFECYCLE_PROCESSOR_BEAN_NAME +
"': using default [" + this.lifecycleProcessor + "]");
}
}
}
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
protected void registerListeners() {
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String lisName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(lisName);
}
}
/**
* Subclasses can invoke this method to register a listener.
* Any beans in the context that are listeners are automatically added.
* <p>Note: This method only works within an active application context,
* i.e. when an ApplicationEventMulticaster is already available. Generally
* prefer the use of {@link #addApplicationListener} which is more flexible.
* @param listener the listener to register
* @deprecated as of Spring 3.0, in favor of {@link #addApplicationListener}
*/
@Deprecated
protected void addListener(ApplicationListener<?> listener) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
/**
* Finish the refresh of this context, invoking the LifecycleProcessor's
* onRefresh() method and publishing the
* {@link org.springframework.context.event.ContextRefreshedEvent}.
*/
protected void finishRefresh() {
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
}
/**
* Cancel this context's refresh attempt, resetting the <code>active</code> flag
* after an exception got thrown.
* @param ex the exception that led to the cancellation
*/
protected void cancelRefresh(BeansException ex) {
synchronized (this.activeMonitor) {
this.active = false;
}
}
public void registerShutdownHook() {
if (this.shutdownHook == null) {
// No shutdown hook registered yet.
this.shutdownHook = new Thread() {
@Override
public void run() {
doClose();
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}
public void destroy() {
close();
}
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
// 如果已经注册过JVM关闭的钩子则需要对其进行注销
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
catch (IllegalStateException ex) {
// ignore - VM is already shutting down
}
}
}
}
// 关闭容器
protected void doClose() {
boolean actuallyClose;
//设置容器关闭状态
synchronized (this.activeMonitor) {
actuallyClose = this.active && !this.closed;
this.closed = true;
}
if (actuallyClose) {
if (logger.isInfoEnabled()) {
logger.info("Closing " + this);
}
try {
//发布容器关闭事件
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
// 停止所有生命周期Bean
try {
getLifecycleProcessor().onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
//销毁这个容器缓存的所有单例Bean
destroyBeans();
// 关闭BeanFactory本身
closeBeanFactory();
//调用子类关闭处理
onClose();
synchronized (this.activeMonitor) {
this.active = false;
}
}
}
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
protected void onClose() {
// For subclasses: do nothing by default.
}
public boolean isActive() {
synchronized (this.activeMonitor) {
return this.active;
}
}
public Object getBean(String name) throws BeansException {
return getBeanFactory().getBean(name);
}
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return getBeanFactory().getBean(name, requiredType);
}
public <T> T getBean(Class<T> requiredType) throws BeansException {
return getBeanFactory().getBean(requiredType);
}
public Object getBean(String name, Object... args) throws BeansException {
return getBeanFactory().getBean(name, args);
}
public boolean containsBean(String name) {
return getBeanFactory().containsBean(name);
}
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().isSingleton(name);
}
public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().isPrototype(name);
}
public boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException {
return getBeanFactory().isTypeMatch(name, targetType);
}
public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().getType(name);
}
public String[] getAliases(String name) {
return getBeanFactory().getAliases(name);
}
public boolean containsBeanDefinition(String beanName) {
return getBeanFactory().containsBeanDefinition(beanName);
}
public int getBeanDefinitionCount() {
return getBeanFactory().getBeanDefinitionCount();
}
public String[] getBeanDefinitionNames() {
return getBeanFactory().getBeanDefinitionNames();
}
public String[] getBeanNamesForType(Class<?> type) {
return getBeanFactory().getBeanNamesForType(type);
}
public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
}
public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException {
return getBeanFactory().getBeansOfType(type);
}
public <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException {
return getBeanFactory().getBeansOfType(type, includeNonSingletons, allowEagerInit);
}
public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
throws BeansException {
return getBeanFactory().getBeansWithAnnotation(annotationType);
}
public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) {
return getBeanFactory().findAnnotationOnBean(beanName, annotationType);
}
public BeanFactory getParentBeanFactory() {
return getParent();
}
public boolean containsLocalBean(String name) {
return getBeanFactory().containsLocalBean(name);
}
protected BeanFactory getInternalParentBeanFactory() {
return (getParent() instanceof ConfigurableApplicationContext) ?
((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent();
}
public String getMessage(String code, Object args[], String defaultMessage, Locale locale) {
return getMessageSource().getMessage(code, args, defaultMessage, locale);
}
public String getMessage(String code, Object args[], Locale locale) throws NoSuchMessageException {
return getMessageSource().getMessage(code, args, locale);
}
public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
return getMessageSource().getMessage(resolvable, locale);
}
private MessageSource getMessageSource() throws IllegalStateException {
if (this.messageSource == null) {
throw new IllegalStateException("MessageSource not initialized - " +
"call 'refresh' before accessing messages via the context: " + this);
}
return this.messageSource;
}
protected MessageSource getInternalParentMessageSource() {
return (getParent() instanceof AbstractApplicationContext) ?
((AbstractApplicationContext) getParent()).messageSource : getParent();
}
public Resource[] getResources(String locationPattern) throws IOException {
return this.resourcePatternResolver.getResources(locationPattern);
}
public void start() {
getLifecycleProcessor().start();
publishEvent(new ContextStartedEvent(this));
}
public void stop() {
getLifecycleProcessor().stop();
publishEvent(new ContextStoppedEvent(this));
}
public boolean isRunning() {
return getLifecycleProcessor().isRunning();
}
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
protected abstract void closeBeanFactory();
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
private class BeanPostProcessorChecker implements BeanPostProcessor {
private final ConfigurableListableBeanFactory beanFactory;
private final int beanPostProcessorTargetCount;
public BeanPostProcessorChecker(ConfigurableListableBeanFactory beanFactory, int beanPostProcessorTargetCount) {
this.beanFactory = beanFactory;
this.beanPostProcessorTargetCount = beanPostProcessorTargetCount;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean != null && !(bean instanceof BeanPostProcessor) &&
this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
if (logger.isInfoEnabled()) {
logger.info("Bean '" + beanName + "' of type [" + bean.getClass() +
"] is not eligible for getting processed by all BeanPostProcessors " +
"(for example: not eligible for auto-proxying)");
}
}
return bean;
}
}
private class ApplicationListenerDetector implements MergedBeanDefinitionPostProcessor {
private final Map<String, Boolean> singletonNames = new ConcurrentHashMap<String, Boolean>();
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanDefinition.isSingleton()) {
this.singletonNames.put(beanName, Boolean.TRUE);
}
}
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
// potentially not detected as a listener by getBeanNamesForType retrieval
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
addApplicationListener((ApplicationListener<?>) bean);
}
else if (flag == null) {
if (logger.isWarnEnabled() && !containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.put(beanName, Boolean.FALSE);
}
}
return bean;
}
}
}
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
/**是否允许Bean Definition 被重写**/
private Boolean allowBeanDefinitionOverriding;
private Boolean allowCircularReferences;
/** BeanFactory*/
private DefaultListableBeanFactory beanFactory;
/** BeanFactory的监视器*/
private final Object beanFactoryMonitor = new Object();
public AbstractRefreshableApplicationContext() {
}
public AbstractRefreshableApplicationContext(ApplicationContext parent) {
super(parent);
}
public void setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) {
this.allowBeanDefinitionOverriding = allowBeanDefinitionOverriding;
}
/**
* 设置是否允许bean之间循环引用,并自动尝试解决问题。默认是true,如果将该值设置为false是完全禁止循环引用
* 在出现循环引用则抛出一个异常。
*/
public void setAllowCircularReferences(boolean allowCircularReferences) {
this.allowCircularReferences = allowCircularReferences;
}
@Override
protected final void refreshBeanFactory() throws BeansException {
// 如果已经存在内部BeanFactory,则销毁Bean同时关闭BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//为当前上下文创建一个BeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//设置beanFactory序列化ID
beanFactory.setSerializationId(getId());
//自定义BeanFactory
customizeBeanFactory(beanFactory);
// 调用子类的方法,加载BeanDefinition
loadBeanDefinitions(beanFactory);
//初始化内部BeanFactory
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
@Override
protected void cancelRefresh(BeansException ex) {
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory != null)
this.beanFactory.setSerializationId(null);
}
super.cancelRefresh(ex);
}
@Override
protected final void closeBeanFactory() {
synchronized (this.beanFactoryMonitor) {
this.beanFactory.setSerializationId(null);
this.beanFactory = null;
}
}
/**
* 判断内部BeanFactory对象是否不为null
*/
protected final boolean hasBeanFactory() {
synchronized (this.beanFactoryMonitor) {
return (this.beanFactory != null);
}
}
/**
* 获取内部BeanFactory
**/
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return this.beanFactory;
}
}
/**
* 为当前上下文创建一个内部BeanFactory对象
*/
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
/**
* 自定义内部BeanFactory
*/
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
}
/**
* 加载BeanDefinition
*/
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws BeansException, IOException;
}
/**
* WebApplicationContext实现类
*/
public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
/** 跟上下问的默认配置文件*/
public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
/** 配置文件的默认前缀 */
public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
/** 配置文件的默认扩展名 */
public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
/**
* Loads the bean definitions via an XmlBeanDefinitionReader.
* 通过XmlBeanDefinitionReader加载Bean Definition
*/
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//对给定的BeanFactory创建一个XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//配置XmlBeanDefinitionReader
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 初始化Bean DefinitionReader
initBeanDefinitionReader(beanDefinitionReader);
//加载Bean Definition
loadBeanDefinitions(beanDefinitionReader);
}
/**
*
*/
protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
// 获取配置文件路径
String[] configLocations = getConfigLocations();
// 如果配置文件路径不为空
if (configLocations != null) {
// 加载所有配置文件
for (String configLocation : configLocations) {
reader.loadBeanDefinitions(configLocation);
}
}
}
/**
*
*/
@Override
protected String[] getDefaultConfigLocations() {
//如果命名空间不是null 则配置文件的路径是/WEB-INF/{nameSpace}.xml
if (getNamespace() != null) {
return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
}
else {
return new String[] {DEFAULT_CONFIG_LOCATION};
}
}
}
相关推荐
ysoserial是一个用于生成利用不安全的Java对象反序列化的有效负载的概念验证工具。它包含一系列在常见Java库中发现的"gadget chains",可以在特定条件下利用执行不安全的反序列化操作的Java应用程序。ysoserial项目最初在2015年AppSecCali会议上提出,包含针对Apache Commons Collections(3.x和4.x版本)、Spring Beans/Core(4.x版本)和Groovy(2.3.x版本)的利用链
1、嵌入式物联网单片机项目开发例程,简单、方便、好用,节省开发时间。 2、代码使用IAR软件开发,当前在CC2530上运行,如果是其他型号芯片,请自行移植。 3、软件下载时,请注意接上硬件,并确认烧录器连接正常。 4、有偿指导v:wulianjishu666; 5、如果接入其他传感器,请查看账号发布的其他资料。 6、单片机与模块的接线,在代码当中均有定义,请自行对照。 7、若硬件有差异,请根据自身情况调整代码,程序仅供参考学习。 8、代码有注释说明,请耐心阅读。 9、例程具有一定专业性,非专业人士请谨慎操作。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
**Oracle 10g DBA学习手册:安装Oracle和构建数据库** **目的:** 本章节旨在指导您完成Oracle数据库软件的安装和数据库的创建。您将通过Oracle Universal Installer (OUI)了解软件安装过程,并学习如何利用Database Configuration Assistant (DBCA)创建附加数据库。 **主题概览:** 1. 利用Oracle Universal Installer (OUI)安装软件 2. 利用Database Configuration Assistant (DBCA)创建数据库 **第2章:Oracle软件的安装与数据库构建** **Oracle Universal Installer (OUI)的运用:** Oracle Universal Installer (OUI)是一个图形用户界面(GUI)工具,它允许您查看、安装和卸载机器上的Oracle软件。通过OUI,您可以轻松地管理Oracle软件的安装和维护。 **安装步骤:** 以下是使用OUI安装Oracle软件并创建数据库的具体步骤:
消防验收过程服务--现场记录表.doc
数据库管理\09-10年第1学期数据库期末考试试卷A(改卷参考).doc。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
职业暴露后的处理流程.docx
Java Web开发短消息系统
项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 服务器:tomcat7
这是一款可以配置过滤目录及过滤的文件后缀的工具,并且支持多个项目同时输出导出,并过滤指定不需要导出的目录及文件后缀。 导出后将会保留原有的路径,并在新的文件夹中体现。
Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
YOLO算法-挖掘机与火焰数据集-7735张图像带标签-挖掘机.zip
操作系统实验 Ucore lab5
IMG_5950.jpg
竞选报价评分表.docx
java系统,mysql、springboot等框架
1、嵌入式物联网单片机项目开发例程,简单、方便、好用,节省开发时间。 2、代码使用IAR软件开发,当前在CC2530上运行,如果是其他型号芯片,请自行移植。 3、软件下载时,请注意接上硬件,并确认烧录器连接正常。 4、有偿指导v:wulianjishu666; 5、如果接入其他传感器,请查看账号发布的其他资料。 6、单片机与模块的接线,在代码当中均有定义,请自行对照。 7、若硬件有差异,请根据自身情况调整代码,程序仅供参考学习。 8、代码有注释说明,请耐心阅读。 9、例程具有一定专业性,非专业人士请谨慎操作。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
内容概要:本文详细讲解了搜索引擎的基础原理,特别是索引机制、优化 like 前缀模糊查询的方法、建立索引的标准以及针对中文的分词处理。文章进一步深入探讨了Lucene,包括它的使用场景、特性、框架结构、Maven引入方法,尤其是Analyzer及其TokenStream的实现细节,以及自定义Analyzer的具体步骤和示例代码。 适合人群:数据库管理员、后端开发者以及希望深入了解搜索引擎底层实现的技术人员。 使用场景及目标:适用于那些需要优化数据库查询性能、实施或改进搜索引擎技术的场景。主要目标在于提高数据库的访问效率,实现高效的数据检索。 阅读建议:由于文章涉及大量的技术术语和实现细节,建议在阅读过程中对照实际开发项目,结合示例代码进行实践操作,有助于更好地理解和吸收知识点。