- java配置类,类似下列代码
@Configuration
@ComponentScan(basePackageClasses = { AppConfig.class})
@EnableWebMvc
@PropertySource({ "classpath:/application.properties", "classpath:/redis.properties" })
public class AppConfig
- web.xml配置
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.test.AppConfig</param-value>
</init-param>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
- DispatcherServlet父类FrameworkServlet、HttpServletBean,HttpServletBean继承了HttpServlet,因此DispatcherServlet能从init方法中开始加载spring各组建。DispatcherServlet在override init()方法中调用了FrameworkServlet中的initServletBean方法。
try {
//初始化WebApplicationContext
this.webApplicationContext = initWebApplicationContext();
//空方法 用于子类复写
initFrameworkServlet();
}
- 在FrameworkServlet的createWebApplicationContext方法
protected WebApplicationContext createWebApplicationContext(ApplicationContext parent) {
//获取web.xml配置contextClass参数 AnnotationConfigWebApplicationContext
Class<?> contextClass = getContextClass();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Servlet with name '" + getServletName() +
"' will try to create custom WebApplicationContext context of class '" +
contextClass.getName() + "'" + ", using parent context [" + parent + "]");
}
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException(
"Fatal initialization error in servlet with name '" + getServletName() +
"': custom WebApplicationContext class [" + contextClass.getName() +
"] is not of type ConfigurableWebApplicationContext");
}
//初始化AnnotationConfigWebApplicationContext bean
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
wac.setEnvironment(getEnvironment());
wac.setParent(parent);
//设置ConfigLocation属性为web.xml配置contextConfigLocation
wac.setConfigLocation(getContextConfigLocation());
//在此方法调用AnnotationConfigWebApplicationContext.refresh方法
//refresh方法负责spring bean加载等初始化工作
configureAndRefreshWebApplicationContext(wac);
return wac;
}
- AnnotationConfigWebApplicationContext refresh方法
refresh->obtainFreshBeanFactory->refreshBeanFactory->loadBeanDefinitions负责加载BeanDefinition
loadBeanDefinitions代码片段:
//这里获取的是web.xml配置contextConfigLocation
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (String configLocation : configLocations) {
try {
//初始化com.test.AppConfig bean
Class<?> clazz = getClassLoader().loadClass(configLocation);
//加载AppConfig指定的ComponentScan范围内的bean
reader.register(clazz);
}
catch (ClassNotFoundException ex) {
int count = scanner.scan(configLocation);
}
}
}
- @configuration注解的类由ConfigurationClassPostProcessor类解析。
- ConfigurationClassParser负责具体解析。