前面的话
前面两篇文章主要是走读了springboot启动时的准备阶段,本文正式进入重点的阶段。即spring context的生成。即如下代码:
//生成spring的context
context = createApplicationContext();
// 异常上报
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,new Class[] { ConfigurableApplicationContext.class }, context);
//准备spring context
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//组装spring context,这一步是重点。主要是spring的机制
refreshContext(context);
下面来分别走读每行代码。
createApplicationContext
createApplicationContext的代码如下:
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
根据不同的webType初始化不同的context。如果是servlet,则通过反射,初始化org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
,如果是reactive类型,则初始化org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext
,如果都不是上面的类型,则初始化org.springframework.context.annotation.AnnotationConfigApplicationContext
.
本文主要走读servlet类型。下面主要看AnnotationConfigServletWebServerApplicationContext
的类图。
这里看下初始化AnnotationConfigServletWebServerApplicationContext
干了哪些事情。
由于该类继承了GenericApplicationContext
,GenericApplicationContext
中的构造方法里初始化了beanfactory。
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
这里直接new出一个DefaultListableBeanFactory
出来。
AnnotationConfigServletWebServerApplicationContext
的无参构造方法里做了哪些事情呢?
public AnnotationConfigServletWebServerApplicationContext() {
//注解相关的处理
this.reader = new AnnotatedBeanDefinitionReader(this);
//scan相关处理
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
初始化reader和scanner。具体做的事情是什么呢?
new AnnotatedBeanDefinitionReader(this);
的代码如下:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
代码中this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
是注册Conditional注解家族的处理类。Conditional注解主要作用是,注册满足条件的bean,Conditional注解家族有如下成员:
当然,我们也可以自定义条件,只需要实现
Condition
接口。定义如下:
public interface Condition {
/**
* Determine if the condition matches.
* @param context the condition context
* @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
* or {@link org.springframework.core.type.MethodMetadata method} being checked
* @return {@code true} if the condition matches and the component can be registered,
* or {@code false} to veto the annotated component's registration
*/
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
然后在使用的时候,在类或者方法上使用@Conditional(yourconditon.class)
代码中AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
主要是实例化spring相关注解的bean。
代码如下
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
//@Order的处理bean
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
//@Lazy,@Qualifier的处理bean
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//@Configuration 注解的bean注册
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//@Autowired 和@Value注解的bean注册。
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
//java 自有注解的处理,如@Resource,@PostConstruct,@PreDestroy等
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
// JPA相关注解的处理
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//@EventListener注解的处理
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
// 事件工厂的默认实现
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
接下来,走读this.scanner = new ClassPathBeanDefinitionScanner(this);
代码如下:
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
这段代码主要是注册扫描的默认过滤规则,默认规则扫描@Component ,@Repository,@Service,@Controller等及JAVAEE6的@ManagedBean和JSR-330的@Named。
至此,context的初始化算是告一段落了,总结下来,在初始化context时,做了哪些事情呢?
1、通过webType,获取不同的context class,这里以servlet为例走读。通过反射初始化AnnotationConfigServletWebServerApplicationContext
2、在context例初始化beanFactory。new一个DefaultListableBeanFactory。
3、注册bean的处理类。如:conditional,@order,@lazy,@autowared等注解的处理。
4、注册扫描规则等。