我们这次来叭叭一下 Spring 的源码, 这次博客主要来说说 Spring 源码, 先粗略的撸一遍, 下篇博客选几个重点去说, 由于过于复杂, 我也是看了一点点, 我们先来过一遍源码, 然后上流程图, 最后我们再回头总结一下, 我们来循序渐进的叭叭一下.
我们来回顾一下上次 Spring 博客的内容, 每次都有用到 AnnotationConfigApplicationContext 来加载我们的配置类, 我们就从这里开始.
- /**
- * Create a new AnnotationConfigApplicationContext, deriving bean definitions
- * from the given annotated classes and automatically refreshing the context. 创建新的注释 configapplicationcontext, 获得 bean 定义并自动刷新上下文.
- * @param annotatedClasses one or more annotated classes, 我们的配置类
- * e.g. {@link Configuration @Configuration} classes
- */
- public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
- this();
- register(annotatedClasses);
- refresh();
- }
翻译过来就是 "创建新的注释 configapplicationcontext, 获得 bean 定义并自动刷新上下文". 三个方法, 我们先来一个个看, 优先看父类有没有构造方法. AnnotationConfigApplicationContext 继承了 GenericApplicationContext 类, 所以我们先看 GenericApplicationContext 类的构造方法. 代码很简单
父类构造方法
- /**
- * Create a new GenericApplicationContext.
- * @see #registerBeanDefinition
- * @see #refresh
- */
- public GenericApplicationContext() {
- this.beanFactory = new DefaultListableBeanFactory();
- }
这里创建了一个新的 DefaultListableBeanFactory 对象, 也是我们熟悉的 beanFactory 对象, 记住是 DefaultListableBeanFactory 对象. 我们回到 AnnotationConfigApplicationContext 的 this 方法.
- this
- /**
- * Create a new AnnotationConfigApplicationContext that needs to be populated
- * through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
- */
- public AnnotationConfigApplicationContext() {
- this.reader = new AnnotatedBeanDefinitionReader(this);// 注解类型的解析器
- this.scanner = new ClassPathBeanDefinitionScanner(this);// 包扫描器
- }
再往下扒一层. 看一下那个 AnnotatedBeanDefinitionReader 注解类型的解析器是怎么创建的, 里面都有什么.
- /**
- * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry.
- * If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext},
- * the {@link Environment} will be inherited, otherwise a new
- * {@link StandardEnvironment} will be created and used.
- * @param registry the {@code BeanFactory} to load bean definitions into,
- * in the form of a {@code BeanDefinitionRegistry}
- * @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
- * @see #setEnvironment(Environment)
- */
- public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
- this(registry, getOrCreateEnvironment(registry)); // 优先设置了环境并存在缓存内
- }
设置了环境, 将我们的 beanFactory 作为参数, 做了 this 调用,
- /**
- * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using
- * the given {@link Environment}. 用 registry 和 Environment 创建一个新的 AnnnotatedBeanDefinitionReader
- * @param registry the {@code BeanFactory} to load bean definitions into,
- * in the form of a {@code BeanDefinitionRegistry}
- * @param environment the {@code Environment} to use when evaluating bean definition
- * profiles.
- * @since 3.1
- */
- 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);
- }
前三行不用看, 第四行是用来解析我们 @Conditional 注解的. 可以自己打开瞧瞧源代码. 我们直接看第五行 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); 也是很重要的代码, 我们继续叭叭.
- /**
- * Register all relevant annotation post processors in the given registry.
- * @param registry the registry to operate on
- * @param source the configuration source element (already extracted)
- * that this registration was triggered from. May be {@code null}.
- * @return a Set of BeanDefinitionHolders, containing all bean definitions
- * that have actually been registered by this call
- */
- public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
- BeanDefinitionRegistry registry, @Nullable Object source) {
- DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
- if (beanFactory != null) {
- if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
- beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
- }
- if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
- beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
- }
- }
- Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
- 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));
- }
- 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.
- 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.
- 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));
- }
- 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;
- }
原文的注释为在给定的注册器中处理所有有意义的后置处理器, 基本就是是否包含 ***, 如果包含就 set 进去. 这段代码是用来初始化内部的组件的. 走到这里就已经初始化的 Bean 定义. 也就是说我们的容器已经注入了定义信息, 还未实例化.
this 方法的上半部分就说完了, 我们再来看下半部分的 new ClassPathBeanDefinitionScanner, 创建一个类路径扫描器, 这个代码不多, 就是判断我们是否使用默认的类路径扫描器.
- /**
- * Create a new {@code ClassPathBeanDefinitionScanner} for the given bean factory and
- * using the given {@link Environment} when evaluating bean definition profile metadata.
- * @param registry the {@code BeanFactory} to load bean definitions into, in the form
- * of a {@code BeanDefinitionRegistry}
- * @param useDefaultFilters whether to include the default filters for the
- * {@link org.springframework.stereotype.Component @Component},
- * {@link org.springframework.stereotype.Repository @Repository},
- * {@link org.springframework.stereotype.Service @Service}, and
- * {@link org.springframework.stereotype.Controller @Controller} stereotype annotations
- * @param environment the Spring {@link Environment} to use when evaluating bean
- * definition profile metadata
- * @param resourceLoader the {@link ResourceLoader} to use
- * @since 4.3.6
- */
- 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);
- }
我们来直接看一下第 23 行代码, 是否注册一个默认的过滤器 (扫描策略).25 行设置环境, 26 行设置资源加载器.
到这里就已经制定好了我们的扫描策略了.
有点乱啊梳理一下.
register(annotatedClasses)
this 部分就说你完了, 再来看看 register(annotatedClasses); 字面意思来看是带着我们的配置文件注册, 我们来看一下代码.
- /**
- * Register one or more annotated classes to be processed.
- * <p>Note that {@link #refresh()} must be called in order for the context
- * to fully process the new classes.
- * @param annotatedClasses one or more annotated classes,
- * e.g. {@link Configuration @Configuration} classes
- * @see #scan(String...)
- * @see #refresh()
- */
- public void register(Class<?>... annotatedClasses) {
- Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
- this.reader.register(annotatedClasses);
- }
用我们上一步的 reader 解析器去注册, 里面是一个循环方法. 最终调用 doRegisterBean 来真正的注册. 这一步我们先来简单的叫做注册吧.
直到这里其实我们容器还是没有创建的, 这些都是一些前期的准备工作. 最后也是最关键的一步才是我们的容器的实例化. refresh() 方法. 内容超多.
- @Override
- public void refresh() throws BeansException, IllegalStateException {
- synchronized (this.startupShutdownMonitor) {
- // Prepare this context for refreshing.
- prepareRefresh();
- // Tell the subclass to refresh the internal bean factory.
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
- // Prepare the bean factory for use in this context.
- prepareBeanFactory(beanFactory);
- try {
- // Allows post-processing of the bean factory in context subclasses.
- postProcessBeanFactory(beanFactory);
- // Invoke factory processors registered as beans in the context.
- invokeBeanFactoryPostProcessors(beanFactory);
- // Register bean processors that intercept bean creation.
- registerBeanPostProcessors(beanFactory);
- // Initialize message source for this context.
- initMessageSource();
- // Initialize event multicaster for this context.
- initApplicationEventMulticaster();
- // Initialize other special beans in specific context subclasses.
- onRefresh();
- // Check for listener beans and register them.
- registerListeners();
- // Instantiate all remaining (non-lazy-init) singletons.
- finishBeanFactoryInitialization(beanFactory);
- // Last step: publish corresponding event.
- finishRefresh();
- }
- catch (BeansException ex) {
- if (logger.isWarnEnabled()) {
- logger.warn("Exception encountered during context initialization -" +
- "cancelling refresh attempt:" + ex);
- }
- // Destroy already created singletons to avoid dangling resources.
- destroyBeans();
- // Reset 'active' flag.
- cancelRefresh(ex);
- // Propagate exception to caller.
- throw ex;
- }
- finally {
- // Reset common introspection caches in Spring's core, since we
- // might not ever need metadata for singleton beans anymore...
- resetCommonCaches();
- }
- }
- }
我们来逐个方法看一下都是做什么的.
prepareRefresh() 创建早期程序监听器.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory() 通知子类刷新 Bean 工厂
prepareBeanFactory(beanFactory) 配置工厂上下文.
postProcessBeanFactory(beanFactory) 处理 Bean 工厂的后置处理
invokeBeanFactoryPostProcessors 实例化并调用所有注册的 Bean 工厂的后置处理器
registerBeanPostProcessors(beanFactory) 注册 Bean 工厂的后置处理器
initMessageSource() 初始化消息源
initApplicationEventMulticaster() 初始化事件多播器
onRefresh() 初始化特殊定义的 Bean
registerListeners() 注册事件监听器
finishBeanFactoryInitialization(beanFactory) 实例化剩余非懒加载 Bean
finishRefresh() 事件发布
resetCommonCaches() 刷新缓存
就这样我们的 Bean 工厂就创建完成了. 看着如此简单吧. 后面我们来详细看一下. 内部还有超多的东西. Spring 源码不建议太过于深入的学习, 容易陷进去....
最近搞了一个个人公众号, 会每天更新一篇原创博文, java,python, 自然语言处理相关的知识有兴趣的小伙伴可以关注一下.
来源: https://www.cnblogs.com/cxiaocai/p/11574879.html