Spring 容器类的加载成一个Bean,其中大概分成2大步,第一步就是类解析成一个BeanDefinition(Bean定义),第二步就是将BeanDefinition创建成一的Bean,经过实例化、属性赋值、初始化最终的一个Bean。先大致有个概念。这次主要是第一步
BeanFactory是Spring顶层核心接口,使用了简单工程模式,负责生产Bean;FactoryBean专门用来修饰普通Bean,getBean的时候获取的是getObject()所获取到的实例,是一个扩展点。
Spring 最重要的概念是 IOC 和 AOP,其中IOC又是Spring中的根基:
加载Spring容器最常用的2中方式
AnnotationConfigApplicationContextClassPathXmlApplicationContext本文主要以AnnotationConfigApplicationContext方式解析,这种设计理念更先进
前置条件:
已经按照前面的步骤自己下载编译了Spring源码能自己写一个模块运行 hello world示例demo:
public class Car { private String name; public Car(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } @Configuration @ComponentScan public class MainApp { @Bean public Car car(){ return new Car("五菱"); } public static void main(String[] args) { ApplicationContext context=new AnnotationConfigApplicationContext(MainApp.class); Car car = context.getBean("car", Car.class); System.out.println(car.getName()); } }AnnotationConfigApplicationContext的结构关系:
DefaultListableBeanFactory的关系图:
可以看出 DefaultListableBeanFactory实现了BeanFactory和 BeanDefinitionRegistry接口
DefaultListableBeanFactory是相当重要的,从字面意思就可以看出它是一个Bean的工厂,什么是Bean的工厂?当然就是用来生产和获得Bean的。
DefaultListableBeanFactory就是我们所说的容器了,里面放着beanDefinitionMap,beanDefinitionNames,beanDefinitionMap是一个hashMap,beanName作为Key,beanDefinition作为Value,beanDefinitionNames是一个集合,里面存放了beanName
实例化了一个AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
重点查看AnnotatedBeanDefinitionReader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); //把ApplicationContext对象赋值给AnnotatedBeanDefinitionReader this.registry = registry; //用户处理条件注解 @Conditional os.name this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); //注册一些内置的后置处理器 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }进入AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
其主要做了2件事情 1.注册内置BeanPostProcessor 2.注册相关的BeanDefinition
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { //注册了实现Order接口的排序器 beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } //设置@AutoWired的候选的解析器:ContextAnnotationAutowireCandidateResolver // getLazyResolutionProxyIfNecessary方法,它也是唯一实现。 //如果字段上带有@Lazy注解,表示进行懒加载 Spring不会立即创建注入属性的实例,而是生成代理对象,来代替实例 if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); /** * 为我们容器中注册了解析我们配置类的后置处理器ConfigurationClassPostProcessor * 名字叫:org.springframework.context.annotation.internalConfigurationAnnotationProcessor */ 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 注解的处理器AutowiredAnnotationBeanPostProcessor * 名字叫:org.springframework.context.annotation.internalAutowiredAnnotationProcessor */ 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)); } /** * 为我们容器注册处理JSR规范的注解处理器CommonAnnotationBeanPostProcessor * org.springframework.context.annotation.internalCommonAnnotationProcessor */ // 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)); } /** * 处理jpa注解的处理器org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor */ // 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)); } /** * 处理监听方法的注解@EventListener解析器EventListenerMethodProcessor */ 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; }这里会一连串注册好几个Bean
在这其中最重要的一个Bean ConfigurationClassPostProcessor
关系 结构图
实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor接口
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)); } 判断容器中是否已经存在了ConfigurationClassPostProcessor Bean如果不存在(当然这里肯定是不存在的),就通过RootBeanDefinition的构造方法获得ConfigurationClassPostProcessor的BeanDefinition,RootBeanDefinition是BeanDefinition的子类执行registerPostProcessor方法,registerPostProcessor方法内部就是注册Bean,当然这里注册其他Bean也是一样的流程。BeanDefinition联系图 向上
BeanMetadataElement接口:BeanDefinition元数据,返回该Bean的来源AttributeAccessor接口:提供对BeanDefinition属性操作能力向下
它是用来描述Bean的,里面存放着关于Bean的一系列信息,比如Bean的作用域,Bean所对应的Class,是否懒加载,是否Primary等等,这个BeanDefinition也相当重要,我们以后会常常和它打交道
registerPostProcessor()方法跟进
private static BeanDefinitionHolder registerPostProcessor( BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) { definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(beanName, definition); return new BeanDefinitionHolder(definition, beanName); }进入org.springframework.context.support.GenericApplicationContext#registerBeanDefinition的方法
进入 org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
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) { // 是不是设置了不允许 相同名称Bean定义 (默认允许存在相同的) 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); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } else if (isConfigurationFrozen()) { clearByTypeCache(); } }第一次进来肯定为空 BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName)
存入map
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName);key:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
value:beanDefinition
DefaultListableBeanFactory中的beanDefinitionMap,beanDefinitionNames也是相当重要的,以后会经常看到它,最好看到它,第一时间就可以反应出它里面放了什么数据 这里仅仅是注册,可以简单的理解为把一些原料放入工厂,工厂还没有真正的去生产。
实例化完AnnotatedBeanDefinitionReader 可以看出 beanDefinitionMap创建了 5个 beanDefinition
因为Spring正在的ClassPathBeanDefinitionScanner并不是使用this()方法初始化的这个扫描器,进入下一步
关键方法是doRegisterBean方法 org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean
这方法的主要作用是把我们的 配置类,也是ApplicationContext context=new AnnotationConfigApplicationContext(MainApp.class); 传进来的 MainApp.class,注册(就是put到map里面,注册听起来高大上一点)容器中
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) { //AnnotatedGenericBeanDefinition可以理解为一种数据结构,是用来描述Bean的,这里的作用就是把传入的标记了注解的类 存储@Configuration注解注释的类 //转为AnnotatedGenericBeanDefinition数据结构,里面有一个getMetadata方法,可以拿到类上的注解 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass); //判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析 if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; } abd.setInstanceSupplier(supplier); //解析bean的作用域,如果没有设置的话,默认为单例 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); abd.setScope(scopeMetadata.getScopeName()); //获得beanName String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); //解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); 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)); } } } if (customizers != null) { for (BeanDefinitionCustomizer customizer : customizers) { customizer.customize(abd); } } BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); //注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册, //DefaultListableBeanFactory维护着一系列信息,比如beanDefinitionNames,beanDefinitionMap //beanDefinitionNames是一个List<String>,用来保存beanName //beanDefinitionMap是一个Map,用来保存beanName和beanDefinition BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }在这里又要说明下,以常规方式去注册配置类,此方法中除了第一个参数,其他参数都是默认值。
通过AnnotatedGenericBeanDefinition的构造方法,获得配置类的BeanDefinition,这里是不是似曾相似,在注册ConfigurationClassPostProcessor类的时候,也是通过构造方法去获得BeanDefinition的,只不过当时是通过RootBeanDefinition去获得,现在是通过AnnotatedGenericBeanDefinition去获得。判断需不需要跳过注册,Spring中有一个@Condition注解,如果不满足条件,就会跳过这个类的注册。然后是解析作用域,如果没有设置的话,默认为单例。获得BeanName。解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description。限定符处理,不是特指@Qualifier注解,也有可能是Primary,或者是Lazy,或者是其他(理论上是任何注解,这里没有判断注解的有效性)。把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中(这个不是很重要,可以简单的理解为方便传参)。注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去进入BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry)方法
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())
就是注册到容器中
这是非常核心的一个方法,里面一共12大步,调用链非常深,分批次解析
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //1:刷新预处理,和主流程关系不大,就是保存了容器的启动时间,启动标志等 prepareRefresh(); //2:获取告诉子类初始化Bean工厂 不同工厂不同实现 // DefaultListableBeanFactory实现了ConfigurableListableBeanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //3:对bean工厂进行填充属性 prepareBeanFactory(beanFactory); try { // 4:留个子类去实现该接口 postProcessBeanFactory(beanFactory); // 5:调用我们的bean工厂的后置处理器. 1. 会在此将class扫描成beanDefinition 2.bean工厂的后置处理器调用 invokeBeanFactoryPostProcessors(beanFactory); // 6:注册我们bean的后置处理器 registerBeanPostProcessors(beanFactory); // 7:初始化国际化资源处理器. initMessageSource(); // 8:创建事件多播器 initApplicationEventMulticaster(); // 9:这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomcat的. onRefresh(); // 10:把我们的事件监听器注册到多播器上 registerListeners(); // 11:实例化我们剩余的单实例bean. finishBeanFactoryInitialization(beanFactory); // 12:最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的) 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(); } } }目标是分析前五个小方法:
刷新预处理,和主流程关系不大,就是保存了容器的启动时间,启动标志等。
这个方法和主流程关系也不是很大,可以简单的认为,就是把beanFactory取出来而已。XML模式下会在这里读取BeanDefinition
对bean工厂进行填充属性
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { //设置bean工厂的类加载器为当前application应用的加载器 beanFactory.setBeanClassLoader(getClassLoader()); //为bean工厂设置我们标准的SPEL表达式解析器对象StandardBeanExpressionResolver beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //为我们的bean工厂设置了一个propertityEditor 属性资源编辑器对象(用于后面的给bean对象赋值使用) beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //注册了一个完整的ApplicationContextAwareProcessor 后置处理器用来处理ApplicationContextAware接口的回调方法 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); /** * * 忽略以下接口的bean的 接口函数方法。 在populateBean时 * 因为以下接口都有setXXX方法, 这些方法不特殊处理将会自动注入容器中的bean */ beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); /** * 当注册了依赖解析后,例如当注册了对 BeanFactory.class 的解析依赖后, * 当 bean 的属性注 入的时候, 一旦检测到属性为 BeanFactory 类型便会将 beanFactory 的实例注入进去。 * 知道为什么可以 * @Autowired * ApplicationContext applicationContext 就是因为这里设置了 */ beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); //注册了一个事件监听器探测器后置处理器接口 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // 处理aspectj的 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } //注册了bean工厂的内部的bean if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { //环境 beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { //环境系统属性 beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { //系统环境 beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }主要做了如下的操作:
设置了一个类加载器设置了bean表达式解析器添加了属性编辑器的支持添加了一个后置处理器:ApplicationContextAwareProcessor,此后置处理器实现了BeanPostProcessor接口设置了一些忽略自动装配的接口设置了一些允许自动装配的接口,并且进行了赋值操作在容器中还没有XX的bean的时候,帮我们注册beanName为XX的singleton bean这是一个空方法
这是一个非常重要的方法:
处理所有实现了BeanDefinitionRegistryPostProcessor处理器(带注册功能的后置处理器)处理所有实现了BeanFactoryPostProcessor处理器调用我们的bean工厂的后置处理器. 1. 会在此将class扫描成beanDefinition 2.bean工厂的后置处理器调用
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 获取两处存储BeanFactoryPostProcessor的对象 传入供接下来的调用 // 1.当前Bean工厂,2.和我们自己调用addBeanFactoryPostProcessor的自定义BeanFactoryPostProcessor PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }让我们看看第一个小方法的第二个参数:
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() { return this.beanFactoryPostProcessors; }这里获得的是BeanFactoryPostProcessor,当我看到这里的时候,愣住了,通过IDEA的查找引用功能,我发现这个集合永远都是空的,根本没有代码为这个集合添加数据,很久都没有想通,后来才知道我们在外部可以手动添加一个后置处理器,而不是交给Spring去扫描,即:
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class); annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX);只有这样,这个集合才不会为空,但是应该没有人这么做吧,当然也有可能是我孤陋寡闻。
进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { //调用BeanDefinitionRegistryPostProcessor的后置处理器 Begin // 1、定义了一个Set,装载BeanName,后面会根据这个Set,来判断后置处理器是否被执行过了 Set<String> processedBeans = new HashSet<>(); // 2、判断我们的beanFactory实现了BeanDefinitionRegistry(实现了该接口就有注册和获取Bean定义的能力) if (beanFactory instanceof BeanDefinitionRegistry) { //强行把我们的bean工厂转为BeanDefinitionRegistry,因为待会需要注册Bean定义 BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 3、定义了两个List,一个是regularPostProcessors,用来装载BeanFactoryPostProcessor, // 一个是registryProcessors用来装载BeanDefinitionRegistryPostProcessor //保存BeanFactoryPostProcessor类型的后置 BeanFactoryPostProcessor 提供修改 List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); //保存BeanDefinitionRegistryPostProcessor类型的后置处理器 BeanDefinitionRegistryPostProcessor 提供注册 List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // 4、循环我们传递进来的beanFactoryPostProcessors for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { //判断我们的后置处理器是不是BeanDefinitionRegistryPostProcessor if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { //进行强制转化 BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; //调用他作为BeanDefinitionRegistryPostProcessor的处理器的后置方法 registryProcessor.postProcessBeanDefinitionRegistry(registry); //添加到我们用于保存的BeanDefinitionRegistryPostProcessor的集合中 registryProcessors.add(registryProcessor); } else { //若没有实现BeanDefinitionRegistryPostProcessor 接口,那么他就是BeanFactoryPostProcessor //把当前的后置处理器加入到regularPostProcessors中 regularPostProcessors.add(postProcessor); } } // 5、定义一个集合用户保存当前准备创建的BeanDefinitionRegistryPostProcessor List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // 6、去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // 7 、循环筛选出来的匹配BeanDefinitionRegistryPostProcessor的类型名称 for (String ppName : postProcessorNames) { //判断是否实现了PriorityOrdered接口的 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); //同时也加入到processedBeans集合中去 processedBeans.add(ppName); } } // 8、对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 9、把当前的加入到总的里面去 registryProcessors.addAll(currentRegistryProcessors); /** * 10、在这里典型的BeanDefinitionRegistryPostProcessor就是ConfigurationClassPostProcessor * 用于进行bean定义的加载 比如我们的包扫描,@import 等等。。。。。。。。。 */ invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 11 、调用完之后,马上clear掉 currentRegistryProcessors.clear(); //---------------------------------------调用内置实现PriorityOrdered接口ConfigurationClassPostProcessor完毕--优先级No1-End---------------------------------------------------- // 12、去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称(内置的和上面注册的) postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // 循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称 for (String ppName : postProcessorNames) { //表示没有被处理过,且实现了Ordered接口的 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); //同时也加入到processedBeans集合中去 processedBeans.add(ppName); } } // 13、对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 14、把他加入到用于保存到registryProcessors中 registryProcessors.addAll(currentRegistryProcessors); // 15、调用他的后置处理方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 16、调用完之后,马上clear掉 currentRegistryProcessors.clear(); //-----------------------------------------调用自定义Order接口BeanDefinitionRegistryPostProcessor完毕-优先级No2-End------------------------------------------------- // 17、调用没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor //定义一个重复处理的开关变量 默认值为true boolean reiterate = true; //第一次就可以进来 while (reiterate) { //进入循环马上把开关变量给改为false reiterate = false; //去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); //循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称 for (String ppName : postProcessorNames) { //没有被处理过的 if (!processedBeans.contains(ppName)) { //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); //同时也加入到processedBeans集合中去 processedBeans.add(ppName); //再次设置为true reiterate = true; } } // 18、对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 19、把他加入到用于保存到registryProcessors中 registryProcessors.addAll(currentRegistryProcessors); // 20、调用他的后置处理方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //进行clear currentRegistryProcessors.clear(); } //-------------调用没有实现任何优先级接口自定义BeanDefinitionRegistryPostProcessor完毕--End------ // 21、调用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); // 22、调用BeanFactoryPostProcessor 自设的(没有) invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { //23、若当前的beanFactory没有实现了BeanDefinitionRegistry 说明没有注册Bean定义的能力 // 那么就直接调用BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } //-----------------------------------------所有BeanDefinitionRegistryPostProcessor调用完毕--End-------- //-----------------------------------------处理BeanFactoryPostProcessor --Begin----------------------- // 24、获取容器中所有的 BeanFactoryPostProcessor String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); //保存BeanFactoryPostProcessor类型实现了priorityOrdered List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); //保存BeanFactoryPostProcessor类型实现了Ordered接口的 List<String> orderedPostProcessorNames = new ArrayList<>(); //保存BeanFactoryPostProcessor没有实现任何优先级接口的 List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { //processedBeans包含的话,表示在上面处理BeanDefinitionRegistryPostProcessor的时候处理过了 if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } //判断是否实现了PriorityOrdered 优先级最高 else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } //判断是否实现了Ordered 优先级 其次 else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } //没有实现任何的优先级接口的 最后调用 else { nonOrderedPostProcessorNames.add(ppName); } } // 25、排序 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); // 26、先调用BeanFactoryPostProcessor实现了 PriorityOrdered接口的 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } // 27、排序 sortPostProcessors(orderedPostProcessors, beanFactory); // 28、再调用BeanFactoryPostProcessor实现了 Ordered. invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } // 29、调用没有实现任何方法接口的 invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); //---------------------------处理BeanFactoryPostProcessor --End------------------------- // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); //------------------- BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor调用完毕 --End }首先判断beanFactory是不是BeanDefinitionRegistry的实例,当然肯定是的,然后执行如下操作:
定义了一个Set,装载BeanName,后面会根据这个Set,来判断后置处理器是否被执行过了。定义了两个List,一个是regularPostProcessors,用来装载BeanFactoryPostProcessor,一个是registryProcessors用来装载BeanDefinitionRegistryPostProcessor,其中BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor。BeanDefinitionRegistryPostProcessor有两个方法,一个是独有的postProcessBeanDefinitionRegistry方法,一个是父类的postProcessBeanFactory方法。循环传进来的beanFactoryPostProcessors,上面已经解释过了,一般情况下,这里永远都是空的,只有手动add beanFactoryPostProcessor,这里才会有数据。我们假设beanFactoryPostProcessors有数据,进入循环,判断postProcessor是不是BeanDefinitionRegistryPostProcessor,因为BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor,所以这里先要判断是不是BeanDefinitionRegistryPostProcessor,是的话,执行postProcessBeanDefinitionRegistry方法,然后把对象装到registryProcessors里面去,不是的话,就装到regularPostProcessors。定义了一个临时变量:currentRegistryProcessors,用来装载BeanDefinitionRegistryPostProcessor。getBeanNamesForType,顾名思义,是根据类型查到BeanNames,这里有一点需要注意,就是去哪里找,点开这个方法的话,就知道是循环beanDefinitionNames去找,这个方法以后也会经常看到。这里传了BeanDefinitionRegistryPostProcessor.class,就是找到类型为BeanDefinitionRegistryPostProcessor的后置处理器,并且赋值给postProcessorNames。一般情况下,只会找到一个,就是org.springframework.context.annotation.internalConfigurationAnnotationProcessor,也就是ConfigurationAnnotationProcessor。这个后置处理器在上一节中已经说明过了,十分重要。这里有一个问题,为什么我自己写了个类,实现了BeanDefinitionRegistryPostProcessor接口,也打上了@Component注解,但是这里没有获得,因为直到这一步,Spring还没有完成扫描,扫描是在ConfigurationClassPostProcessor类中完成的,也就是下面第一个invokeBeanDefinitionRegistryPostProcessors方法。ps:说明一下 ConfigurationAnnotationProcessor既实现了 PriorityOrdered接口,也实现了Ordered接口,前面处理过了后面就不会再次执行invokeBeanDefinitionRegistryPostProcessors接口处理了。
order值越小越先执行
进行排序,PriorityOrdered是一个排序接口,如果实现了它,就说明此后置处理器是有顺序的,所以需要排序。当然:目前这里只有一个后置处理器,就是ConfigurationClassPostProcessor。
把currentRegistryProcessors合并到registryProcessors,为什么需要合并?因为一开始spring只会执行BeanDefinitionRegistryPostProcessor独有的方法,而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即BeanFactoryProcessor接口中的方法,所以需要把这些后置处理器放入一个集合中,后续统一执行BeanFactoryProcessor接口中的方法。当然目前这里只有一个后置处理器,就是ConfigurationClassPostProcessor。
可以理解为执行currentRegistryProcessors中的ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry方法,这就是Spring设计思想的体现了,在这里体现的就是其中的热插拔,插件化开发的思想。Spring中很多东西都是交给插件去处理的,这个后置处理器就相当于一个插件,如果不想用了,直接不添加就是了。这个方法特别重要,我们后面会详细说来。
清空currentRegistryProcessors,因为currentRegistryProcessors是一个临时变量,已经完成了目前的使命,所以需要清空,当然后面还会用到。
再次根据BeanDefinitionRegistryPostProcessor获得BeanName,然后进行循环,看这个后置处理器是否被执行过了,如果没有被执行过,也实现了Ordered接口的话,把此后置处理器推送到currentRegistryProcessors和processedBeans中。 这里就可以获得我们定义的,并且打上@Component注解的后置处理器了,因为Spring已经完成了扫描,但是这里需要注意的是,由于ConfigurationClassPostProcessor在上面已经被执行过了,所以虽然可以通过getBeanNamesForType获得,但是并不会加入到currentRegistryProcessors和processedBeans。
处理排序。
合并Processors,合并的理由和上面是一样的。
执行我们自定义的BeanDefinitionRegistryPostProcessor。
清空临时变量。
在上面的方法中,仅仅是执行了实现了Ordered接口的BeanDefinitionRegistryPostProcessor,这里是执行没有实现Ordered接口的BeanDefinitionRegistryPostProcessor。
上面的代码是执行子类独有的方法,这里需要再把父类的方法也执行一次。
执行regularPostProcessors中的后置处理器的方法,需要注意的是,在一般情况下,regularPostProcessors是不会有数据的,只有在外面手动添加BeanFactoryPostProcessor,才会有数据。
查找实现了BeanFactoryPostProcessor的后置处理器,并且执行后置处理器中的方法。和上面的逻辑差不多,不再详细说明。
获得所有的BeanName,放入candidateNames数组。
循环candidateNames数组,根据beanName获得BeanDefinition,判断此BeanDefinition是否已经被处理过了。
判断是否是配置类,如果是的话。加入到configCandidates数组,在判断的时候,还会标记配置类属于Full配置类,还是Lite配置类,这里会引发一连串的知识盲点:
3.1 当我们注册配置类的时候,可以不加@Configuration注解,直接使用@Component @ComponentScan @Import @ImportResource等注解,Spring把这种配置类称之为Lite配置类, 如果加了@Configuration注解,就称之为Full配置类。
3.2 如果我们注册了Lite配置类,我们getBean这个配置类,会发现它就是原本的那个配置类,如果我们注册了Full配置类,我们getBean这个配置类,会发现它已经不是原本那个配置类了,而是已经被cgilb代理的类了。
3.3 写一个A类,其中有一个构造方法,打印出“你好”,再写一个配置类,里面有两个被@bean注解的方法,其中一个方法new了A类,并且返回A的对象,把此方法称之为getA,第二个方法又调用了getA方法,如果配置类是Lite配置类,会发现打印了两次“你好”,也就是说A类被new了两次,如果配置类是Full配置类,会发现只打印了一次“你好”,也就是说A类只被new了一次,因为这个类被cgilb代理了,方法已经被改写。
如果没有配置类直接返回。
处理排序。我们找到了一个配置类,就是我们的MainApp上面加了@Configuration注解
解析配置类,可能是Full配置类,也有可能是Lite配置类,这个小方法是此方法的核心,稍后具体说明。
ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry) ... parser.parse(candidates);在第6步的时候,只是注册了部分Bean,像 @Import @Bean等,是没有被注册的,这里统一对这些进行注册。
因为可以有多个配置类,所以需要循环处理。我们的配置类的BeanDefinition是AnnotatedBeanDefinition的实例,所以会进入第一个if:
重点在于doProcessConfigurationClass方法,需要特别注意,最后一行代码,会把configClass放入一个Map,会在上面第7步中用到。
处理我们的@Component注解的
处理@PropertySource注解,@PropertySource注解用来加载properties文件。
获得ComponentScan注解具体的内容,ComponentScan注解除了最常用的basePackage之外,还有includeFilters,excludeFilters等。
判断有没有被@ComponentScans标记,或者被@Condition条件带过,如果满足条件的话,进入if,进行如下操作:
4.1 执行扫描操作,把扫描出来的放入set,这个方法稍后再详细说明。
4.2 循环set,判断是否是配置类,是的话,递归调用parse方法,因为被扫描出来的类,还是一个配置类,有@ComponentScans注解,或者其中有被@Bean标记的方法 等等,所以需要再次被解析。
处理@Import注解,@Import是Spring中很重要的一个注解,正是由于它的存在,让Spring非常灵活,不管是Spring内部,还是与Spring整合的第三方技术,都大量的运用了@Import注解,@Import有三种情况,一种是Import普通类,一种是Import ImportSelector,还有一种是Import ImportBeanDefinitionRegistrar,getImports(sourceClass)是获得import的内容,返回的是一个set,这个方法稍后再详细说明。处理@ImportResource注解。处理@Bean的方法,可以看到获得了带有@Bean的方法后,不是马上转换成BeanDefinition,而是先用一个set接收。定义了一个扫描器scanner,还记不记在new AnnotationConfigApplicationContext的时候,会调用AnnotationConfigApplicationContext的构造方法,构造方法里面有一句 this.scanner = new ClassPathBeanDefinitionScanner(this);当时说这个对象不重要,这里就是证明了。常规用法中,实际上执行扫描的只会是这里的scanner对象。
处理includeFilters,就是把规则添加到scanner。
处理excludeFilters,就是把规则添加到scanner。
解析basePackages,获得需要扫描哪些包,如果为空的话,会默认按照
默认的解析路径
添加一个默认的排除规则:排除自身。
执行扫描,稍后详细说明。
这里需要做一个补充说明,添加规则的时候,只是把具体的规则放入规则类的集合中去,规则类是一个函数式接口,只定义了一个虚方法的接口被称为函数式接口,函数式接口在java8的时候大放异彩,这里只是把规则方塞进去,并没有真正执行匹配规则。
org.springframework.util.ClassUtils#getPackageName(java.lang.String)
public static String getPackageName(String fqClassName) { Assert.notNull(fqClassName, "Class name must not be null"); int lastDotIndex = fqClassName.lastIndexOf(PACKAGE_SEPARATOR); return (lastDotIndex != -1 ? fqClassName.substring(0, lastDotIndex) : ""); }因为basePackages可能有多个,所以需要循环处理,最终会进行Bean的注册。
Spring支持component索引技术,需要引入一个组件,大部分项目没有引入这个组件
把传进来的类似命名空间形式的字符串转换成类似类文件地址的形式,然后在前面加上classpath,即:com.xx=>classpath:com/xx/**/*.class。
根据packageSearchPath,获得符合要求的文件。
循环符合要求的文件,进一步进行判断。 最终会把符合要求的文件,转换为BeanDefinition,并且返回。
注册BeanDefinition
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { for (TypeFilter tf : this.excludeFilters) { if (tf.match(metadataReader, getMetadataReaderFactory())) { return false; } } for (TypeFilter tf : this.includeFilters) { if (tf.match(metadataReader, getMetadataReaderFactory())) { return isConditionMatch(metadataReader); } } return false; } protected boolean matchSelf(MetadataReader metadataReader) { AnnotationMetadata metadata = metadataReader.getAnnotationMetadata(); return metadata.hasAnnotation(this.annotationType.getName()) || (this.considerMetaAnnotations && metadata.hasMetaAnnotation(this.annotationType.getName())); }这里我有一个实现了@Service的类进行匹配,会拿到AnotationTypeMappings, 里面有三个元素
最终会获取到每个元素的 AnnotationType去和@Component比较,相对则返回true
第一个:
第二个:
这里跟的比较深了,我也是看了2遍,可以理解为,除了JDK自带的处理(Spring写的)比如@Service @Component等
最后有2个类满足条件
注册到BeanDefinitionMap中,可以看到多2个Bean
我们来做一个总结,ConfigurationClassPostProcessor中的processConfigBeanDefinitions方法十分重要,主要是完成扫描,最终注册我们定义的Bean。
实例化和注册beanFactory中扩展了BeanPostProcessor的bean。 例如:
AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)初始化国际化资源处理器.不是主线代码忽略,没什么学习价值。 initMessageSource();
创建事件多播器,后续写
模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情。
注册监听器,广播early application events,后续写
实例化所有剩余的(非懒加载)单例 比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。 实例化的过程各种BeanPostProcessor开始起作用。
后续写
最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)
