????????书接前文:Spring5源码之四——refresh方法之prepareBeanFactory(),接下来解读一下postProcessBeanFactory()方法。?
????????(1)该方法由AbstractRefreshableWebApplicationContext实现。
//注册请求/会话范围、 ServletContextAwareProcessor等
public abstract class AbstractRefreshableWebApplicationContext extends AbstractRefreshableConfigApplicationContext
implements ConfigurableWebApplicationContext, ThemeSource {
//省略其他代码......
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
}
(2)在(1)中的addBeanPostProcessor()方法,调用到AbstractBeanFactory类的addBeanPostProcessor()方法。该方法主要是提供给想要实现BeanPostProcessor的第三方框架使用,做一些定制化改造。
@Override
//添加bean的后置处理器
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
this.beanPostProcessors.remove(beanPostProcessor);
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
this.beanPostProcessors.add(beanPostProcessor);
}
(3)在(1)中ignoreDependencyInterface(ServletContextAware.class)和ignoreDependencyInterface(ServletConfigAware.class)的目的是在自动注入时忽略指定的依赖接口。
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
(4)在(1)中registerWebApplicationScopes(beanFactory, this.servletContext)方法,调用到WebApplicationContextUtils类的registerWebApplicationScopes()方法。其主要目的是使用 WebApplicationContext 使用的给定 BeanFactory 注册特定于 Web 的范围(“request”、“session”、“globalSession”、“application”)。
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
@Nullable ServletContext sc) {
beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
if (sc != null) {
ServletContextScope appScope = new ServletContextScope(sc);
beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
// Register as ServletContext attribute, for ContextCleanupListener to detect it.
sc.setAttribute(ServletContextScope.class.getName(), appScope);
}
beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
if (jsfPresent) {
FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
}
}
(5)在(1)中registerEnvironmentBeans()方法,调用到WebApplicationContextUtils类的registerEnvironmentBeans()方法,该方法中WebApplicationContext 使用的给定 BeanFactory 注册特定于 Web 的环境 bean(“contextParameters”、“contextAttributes”)。
public static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf,
@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
if (servletContext != null && !bf.containsBean(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)) {
bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext);
}
if (servletConfig != null && !bf.containsBean(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME)) {
bf.registerSingleton(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME, servletConfig);
}
if (!bf.containsBean(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME)) {
Map<String, String> parameterMap = new HashMap<>();
if (servletContext != null) {
Enumeration<?> paramNameEnum = servletContext.getInitParameterNames();
while (paramNameEnum.hasMoreElements()) {
String paramName = (String) paramNameEnum.nextElement();
parameterMap.put(paramName, servletContext.getInitParameter(paramName));
}
}
if (servletConfig != null) {
Enumeration<?> paramNameEnum = servletConfig.getInitParameterNames();
while (paramNameEnum.hasMoreElements()) {
String paramName = (String) paramNameEnum.nextElement();
parameterMap.put(paramName, servletConfig.getInitParameter(paramName));
}
}
bf.registerSingleton(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME,
Collections.unmodifiableMap(parameterMap));
}
if (!bf.containsBean(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME)) {
Map<String, Object> attributeMap = new HashMap<>();
if (servletContext != null) {
Enumeration<?> attrNameEnum = servletContext.getAttributeNames();
while (attrNameEnum.hasMoreElements()) {
String attrName = (String) attrNameEnum.nextElement();
attributeMap.put(attrName, servletContext.getAttribute(attrName));
}
}
bf.registerSingleton(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME,
Collections.unmodifiableMap(attributeMap));
}
}
(6)看一下(5)中registerSingleton的具体实现。
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
//省略部分代码......
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
//调用DefaultSingletonBeanRegistry父类方法
super.registerSingleton(beanName, singletonObject);
updateManualSingletonNames(set -> set.add(beanName), set -> !this.beanDefinitionMap.containsKey(beanName));
clearByTypeCache();
}
//更新工厂的内部手动单例名称集
private void updateManualSingletonNames(Consumer<Set<String>> action, Predicate<Set<String>> condition) {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
if (condition.test(this.manualSingletonNames)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
action.accept(updatedSingletons);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// Still in startup registration phase
if (condition.test(this.manualSingletonNames)) {
action.accept(this.manualSingletonNames);
}
}
}
//删除有关按类型映射的任何缓存
private void clearByTypeCache() {
this.allBeanNamesByType.clear();
this.singletonBeanNamesByType.clear();
}
}
//------------------------------------------------------------------------------------
//------------------------------DefaultSingletonBeanRegistry类------------------------
//------------------------------------------------------------------------------------
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "Bean name must not be null");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
addSingleton(beanName, singletonObject);
}
}
}
? ? ? ? 至此,postProcessBeanFactory()方法基本分析完毕,spring后续源码未完待续。
|