spring的源码解析一
查看spring源码方法
1,使用intellJ IDEA 反编译class文件,反编译过来的文件不能编辑,也没有注释。
2,使用maven自动下载下来的,此时的文件也不能编辑,有注释。
3,在github上下载spring源码,然后在本地构建。
AnnotationConfigApplicationContext 注解配置应用上下文
下面这行代码就会把spring所有的前提环境都准备好,bean工厂,容器以及对象的实例化都会准备好
AnnotationConfigApplicationContext actxt = new AnnotationConfigApplicationContext(initalizespring.AppConfig.class);
下面我们根据上面actxt对象的创建来进入spring的源码世界吧!
/** * Create a new AnnotationConfigApplicationContext, deriving bean definitions * from the given component classes and automatically refreshing the context. * @param componentClasses one or more component classes — for example, * {@link Configuration @Configuration} classes */ public AnnotationConfigApplicationContext(Class<?>... componentClasses) { // this()中会调用父类的构造方法,然后才调用子类的构造方法,然后才调用到这里 // 在自己的构造方法中初始化一个读取器和扫描器 this(); register(componentClasses); refresh(); }
其中this()中源码如下:
/** * Create a new AnnotationConfigApplicationContext that needs to be populated * through {@link #register} calls and then manually {@linkplain #refresh refreshed}. */ public AnnotationConfigApplicationContext() { // AnnotationConfigApplicationContext有父类,故而这里先调用父类的构造方法,然后才调用子类的构造方法 // 创建一个读取用注解标记的bean定义的读取器,此读取器用于读取有注解的bean // 什么是BeanDefinition??? this.reader = new AnnotatedBeanDefinitionReader(this); //reader的类型是AnnotatedBeanDefinitionReader this.scanner = new ClassPathBeanDefinitionScanner(this); //scanner的类型是ClassPathBeanDefinitionScanner }
上面reader的类型是AnnotatedBeanDefinitionReader,读取被加了注解的bean,AnnotatedBeanDefinition类继承了BeanDefinition,BeanDefinition是spring中bean的定义,它类似于Class类,每个类都有一个Class对象,如果被spring管理,spring使用BeanDefinition来描述它管理的类。因此,reader是读取被加了注解的类的描述bean的读取器。
spring管理者四种bean, 被注解的bean,使用xml描述的bean,使用@bean的bean,spring内部使用的bean
scanner的类型是ClassPathBeanDefinitionScanner,扫描器
第一段代码中执行register(componentClasses);
/** * 注册一个或多个component类去注册,但是注册之后必须手动refresh去触发容器解析注解 * 此方法有两个作用,1,是将配置类注册如AppConfig类,一般是作为构造方法的入参,此时无需手动refresh * 2,将某个未被spring注解的类交给spring去管理,注册后需要手动refresh * Register one or more component classes to be processed. * <p>Note that {@link #refresh()} must be called in order for the context * to fully process the new classes. * @param componentClasses one or more component classes — for example, * {@link Configuration @Configuration} classes * @see #scan(String...) * @see #refresh() */ @Override public void register(Class<?>... componentClasses) { Assert.notEmpty(componentClasses, "At least one component class must be specified"); this.reader.register(componentClasses); }
最终上面的register(componentClasses)会变成执行这段代码:
/** * Register a bean from the given bean class, deriving its metadata from * class-declared annotations. * @param beanClass the class of the bean * @param instanceSupplier a callback for creating an instance of the bean * (may be {@code null}) * @param name an explicit name for the bean * @param qualifiers specific qualifier annotations to consider, if any, * in addition to qualifiers at the bean class level * @param definitionCustomizers one or more callbacks for customizing the * factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag * @since 5.0 */ <T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) { /** * 根据指定的bean创建一个AnnotationGenericBeanDefinition * 这个AnnotationGenericBeanDefinition可以理解为一个数据结构 * 它包含了类的其他信息,比如一些元信息,scope, lazy等 */ AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass); /** * 判断这个类是否需要跳过解析 * 通过代码可以知道spring判断是否跳过解析,主要判断类有没有添加注解,abd.getMetadata()获取元数据 */ if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; } abd.setInstanceSupplier(instanceSupplier); //得到类的作用域 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); //把类的作用域添加到数据结构中 abd.setScope(scopeMetadata.getScopeName()); //通过beanNameGenerator生成类的对象的名字 String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); /** * 处理类中的通用注解 * 主要处理Lazy,DependsOn,Primary,Role,Description五种注解 * 处理完成后依然把他们添加进数据结构 */ AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); /** * 如果向容器注册注解bean定义时,使用了额外的限定符注解则解析 * 关于Qualifier和Primary前面的课当中讲过,主要涉及spring的自动装配 * 这里需要注意的视byName和qualifier视Annotation类型的数组,里面不仅仅是Qualifier注解 * 理论上里面存的是一切注解,所以可以看到下面的代码spring去循环了这个数组 * 然后依次判断注解当中是否包含了Primary和Lazy * qualifiers对象其实是null的,所以使用new AnnotationConfigApplicationContext(initalizespring.AppConfig.class)时并不会执行下面的代码 */ if (qualifiers != null) { for (Class<? extends Annotation> qualifier : qualifiers) { if (Primary.class == qualifier) { abd.setPrimary(true); } else if (Lazy.class == qualifier) { abd.setLazyInit(true); } else { abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } for (BeanDefinitionCustomizer customizer : definitionCustomizers) { customizer.customize(abd); } // BeanDefinitionHolder 这个也是个数据结构,可以理解为一个map对象 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); /** * ScopedProxyMode 知识点比较复杂,需要结合web去理解,现在暂时搁置此问题,后面讲解springmvc时在说 * 代理模型 */ definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); /** * 把上述的数据结构注册给registry * registry就是AnnotationConfigApplication * AnnotationConfigApplication在初始化的时候通过调用父类的构造方法 * 实例化一个DefaultListableBeanFactory * registerBeanDefinition()方法就是把definitionHolder这个数据结构包含的信息注册到 * DefaultListableBeanFactory这个工厂 */ BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }
将definitionHolder注册的代码如下,也就是上面最后一行代码:
/** * Register the given bean definition with the given bean factory. * @param definitionHolder the bean definition including name and aliases * @param registry the bean factory to register with * @throws BeanDefinitionStoreException if registration failed */ public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. String beanName = definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // Register aliases for bean name, if any. /** * 处理别名 */ String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); } } } registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition())的源码如下,下面代码在DefaultListableBeanFactory中,这个类就是大名鼎鼎的spring的bean工厂,由它来创建对象。 public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else { if (logger.isTraceEnabled()) { logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); // 使用一个map维护所有spring管理的bean this.beanDefinitionNames.add(beanName); // beanDefinitionNames是List<String>类型,存放所有bean的名字beanName removeManualSingletonName(beanName); // 为了去重 } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
beanDefinitionMap存放完毕后,里面会存在多个对象(除了业务对象以外的对象),他们就是著名的spring的后置处理器,它是在this.reader = new AnnotatedBeanDefinitionReader(this)初始化时创建的。
上面讲解这么多还没有对象产生,它主要是为了beanDefinitionHolder放入beanDefinitionMap,将beanName放入beanDefinitionNames。看下图(由于原图格式问题,无法上传,这里只能截图上传了)
调用getBean()方法时会调用refresh()方法里面的逻辑。
------未完,待续-----