专业的编程技术博客社区

网站首页 > 博客文章 正文

Sprring注解源码深度分析-上篇(spy注解)

baijin 2024-08-12 13:39:50 博客文章 18 ℃ 0 评论

Spring注解源码深度刨析

1整体执行流程

1.1自定义启动配置类

@Configuration  
@ComponentScan("cn.spring._08springAdvinceAnno")  
@Import({Man.class})  
public class IocConfig {  
}  
 
启动容器的代码  
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationConfig.class); 

1.2初始化整体流程

  1. 在new AnnotationConfigApplicationContext 之后会进入构造器,先初始化父类GenericApplicationContext

2. 调用AnnotationConfigApplicationContext 中的空构造器初始化AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner

3. 调用registry将配置类注册到BeanFactory

4. 执行核心方法Refresh刷新BeanFactory容器

2 初始化阶段

2.1初始化父类容器

调用父类空构造器创建一个DefaultListableBeanFactory。在new DefaultListableBeanFactory的时候初始化了一些属性值。

public GenericApplicationContext() {  
 this.beanFactory = new DefaultListableBeanFactory();  
}


DefaultListableBeanFactory继承图



2.2this()

AnnotationConfigApplicationContext的空参构造器中分别初始化了AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner

2.2.1初始化AnnotatedBeanDefinitionReader

AnnotatedBeanDefinitionReader【作用读取注解的BeanDefinition】,在创建的时候调用(registry,environment)构造器其中environment是从registry中获取到的默认是读取的电脑的Path下边的环境调用的是SystemProperties下边的属性。

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment){  
 this.registry = registry;  
        //创建一个处理@ Conditional评估
 this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);  
 
        //为容器中注册系统的bean定义信息  
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);  
    }  


将registry赋值到成员属性,并new了ConditionEvaluator【作用用于计算内部的类】将registry和environment创建,在ConditionEvaluator【条件装配器】构造器中new了一个ConditionContextImpl并赋值给自己的成员变量。

class ConditionEvaluator {  
 private final ConditionContextImpl context;  
public ConditionEvaluator(@Nullable BeanDefinitionRegistry registry,  
            @Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {  
 
 this.context = new ConditionContextImpl(registry, environment, resourceLoader);  
    }  
}  
 // 这个类主要的作用是封装一些装配器 
public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,  
                @Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {  
            // 初始条件计算器的bean定义注册器  
 this.registry = registry;  
            //初始化bean工厂  
 this.beanFactory = deduceBeanFactory(registry);  
            // 为环境对象赋值  
 this.environment = (environment != null ? environment : deduceEnvironment(registry));  
            //为资源加载器赋值  
 this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));  
 this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);  
}  

到这里ConditionEvaluator整体初始化完了主要初始化ConditionContextImpl里边也封装了一些注册器和BeanFactory,环境,资源加载器,类加载器缓存起来。

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); 为容器注册一些处理器

获取一个Ioc容器
//获取一个IOC容器  
//先判断是否是DefaultListableBeanFactory根据上边的继承图可知不是,然后找父类直接get默认的BeanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);  
if (beanFactory != null) {  
 if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {  
        //设置默认的AnnotationAware排序规则  AnnotationAwareOrderComparator 饿汉式加载
        beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);  
    }  
 if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {  
        //设置默认的AnnotationAutowireCandidateResolver  
        beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());  
 	   //ContextAnnotationAutowireCandidateResolver[作用:providing support for qualifier annotations as well as for lazy resolution] 
    }  
}  

获取到Ioc容器主要初始化了排序规则还有初始化了对懒加载@Lazy注解解析的Resolver


2、创建了一个链表来保存注册的BeanDefinition

Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);  

3、注册一个配置类解析器并保存到容器中

//注册一个配置类解析器的bean定义(ConfigurationClassPostProcessor)  
//先从AbstractApplicationContext抽象类中获取到默认的BeanFactory(DefaultListableBeanFactory)判断成员属性beanDefinitionMap中是否包含internalConfigurationAnnotationProcessor处理器 【很显然不包含】  
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {  
    //ConfigurationClassPostProcessor这个处理器主要解析配置类的信息的处理器很重要
    RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);  
    def.setSource(source);  //这一步为null
   //并添加到容器中 registerPostProcessor这一步 主要创建了BeanDefinitionHolder持有器里边包含BeanDefinition还有beanName,如果有别名还有别名,方便通过beanName来查找【可以见得Spring中设计之巧妙!】
// registerPostProcessor这个方法在转换成持有器的同时,也会忘往DefaultListableBeanFactory的beanDefinitionMap中保存一份key就是beanName(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)value就是处理器
   beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));   
}  

4、设置AutoWired注解解析器的bean定义信息

//设置AutoWired注解解析器的bean定义信息 
//跟上边一样也是从DefaultListable中判断beanDefinitionMap属性中是否包含internalAutowiredAnnotationProcessor处理器【很显然默认是不包含的】
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {  
//同理创建了一个AutowiredAnnotationBeanPostProcessor处理器并创建一个持有器注册到容器中
//持有器就是包含BeanDefinition和这个BeanDefinition的BeanName和别名
//AutowiredAnnotationBeanPostProcessor 对AutowiredAnnotationBean解析器
    RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);  
    def.setSource(source);  
    beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));  
}  

5、检查是否支持JSR250规范支持注入对应处理器

//检查是否支持JSR250规范,如何支持注册 解析JSR250规范的注解  
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {  
// CommonAnnotationBeanPostProcessor主要是针对@Resource注解进行解析的处理器 
    RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);  
    def.setSource(source);  
    beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));  
}  

6、检查是否支持jpa支持注入对应处理器

//检查是否支持jpa,若支持注册解析jpa规范的注解  
//jpa注解(Java Persistence API),是Java EE 5的标准ORM接口,也是ejb3规范的一部分。
// @Entity说明这个class是实体类、@Table是一个do、@Column是一个列名主要兼容Hibernate时代的
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));  
}  

jpa就是典型的ORM思想的应征。


7、注册解析@EventListener的注解

//注册解析@EventListener的注解
//@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));  
} 

事件编码驱动Demo

/** 
 * @Description: 新增mongodb数据事件 Entity
 */  
public class AddDataEvent extends ApplicationEvent {
 public AddDataEvent(Object source) {  
 super(source);  
    }  
 public AddDataEvent(Object source, Class clz, Object data) {  
 super(source);  
 this.clz = clz;  
 this.data = data;  
    }  
 public AddDataEvent(Object source, Class clz, Object data, String modelName, String userAgent) {  
 super(source);  
 this.clz = clz;  
 this.data = data;  
 this.modelName = modelName;  
 this.userAgent = userAgent;  
    }  
    /** 要更新的表对象 **/  
 private Class clz;  
 
    /** 操作的数据**/  
 private Object data;  
 
    /** 模块名称**/  
 private String modelName;  
 
    /** 浏览器标识 **/  
 private String userAgent;  
}  


事件监听器

@Component  
public class AddDataEventListener {  
 private static Logger log = LoggerFactory.getLogger(AddDataEventListener.class);  
    /** 
     * 处理新增数据的事件 
     **/  
    @EventListener  
 public void handleAddEvent(AddDataEvent event) {  
        log.info("发布的data为:{}  ", JSON.toJSONString(event));  
 
    }  
}  

原理在AnnotationConfigUtils#registerAnnotationConfigProcessors注册了BeanDefinition 对应的是EventListenerMethodProcessor对象, AnnotationConfigUtils在AnnotationConfigServletWebServerApplicationContext构造器里被加载DefaultListableBeanFactory#中preInstantiateSingletons -> (beanName为org.springframework.context.event.internalEventListenerProcessor时得到EventListenerMethodProcessor)EventListenerMethodProcessor#afterSingletonsInstantiated this.processBean(factories, beanName, type)然后把要执行的方法封装为ApplicationListenerMethodAdapter -> 添加到listener中 AbstractApplicationEventMulticaster#addApplicationListener该方法在 ApplicationListenerMethodAdapter 利用反射执行

测试类

@Controller  
@RequestMapping("/test")  
public class TestController {  
 
 
   @Resource  
 private ApplicationContext applicationContext;  
 
 
   @ResponseBody  
   @RequestMapping("/testListener")  
 public String testListener(){  
      applicationContext.publishEvent(new AddDataEvent(this,TestController.class,"test"));  
 return "success";  
   }  
} 

8、注册化事件监听工厂处理器

//注册化事件监听工厂处理器  
//主要处理@EventListener注解配合第7步
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));  
}  

小结:AnnotatedBeanDefinitionReader总体来说就是初始化了Ioc容器和各种的BeanDefinition的处理器注册到Ioc的BeanDefinitionMap中容器中。

2.2.2初始化ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner这个类主要用于对classpathDefinition进行扫描器。

1、调用重载参构造器

// registry就是AnnotationConfigApplicationContext本身 useDefaultFilters为true 
使用默认配置环境是System.getProperties()获取到的
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,  
  Environment environment) {  
 this(registry, useDefaultFilters, environment,  
            (registry instanceof ResourceLoader ? (ResourceLoader) registry : null));  
}  
继续调用重载参构造器
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,  
        Environment environment, @Nullable ResourceLoader resourceLoader) {  
 this.registry = registry;  
    //是默认的配置
 if (useDefaultFilters) {  
        //注册包扫描默认的规则  
        registerDefaultFilters();  
    }  
    //设置环境  
    setEnvironment(environment);  
    //设置资源加载器  
    setResourceLoader(resourceLoader);  
}

3、注册默认过滤器registerDefaultFilters

protected void registerDefaultFilters() {  
    //@Compent  @Service @Repository @Controller @Aspectj  
//将@Component加入到includeFilters过滤器  AnnotationTypeFilter包含了注解的类和是否是原注解的类
 this.includeFilters.add(new AnnotationTypeFilter(Component.class));  
 try {  
        //jsr250规范的组件  @Resource过滤器
 this.includeFilters.add(new AnnotationTypeFilter(  
                ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));  
        logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");  
    }  
 try {  
        //可以支持jsr330的注解  
 this.includeFilters.add(new AnnotationTypeFilter(  
                ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));  
    }  
} 


4、设置环境

这一步很简单就是把获取到的环境设置到成员属性。

5、设置资源加载器

//上边重载方法中直接设置AnnotationConfigApplicationContext为resourceLoader
public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {  
//判断resourceLoader是否属于resourcePatternResolver是的话强转不是的话PathMatchingResourcePatternResolver创建一个【默认是AnnotationConfigApplicationContext类型】主要作用是解析本地的pattern(类似与正则匹配url)
 this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);  
//创建一个CachingMetadataReaderFactory 并且往DefaultResourceLoader中缓存resourceCaches缓存了一份MetadataReader
//metadataReader对一个类的各种元数据都封装成一个MetadataReader  一个类的元数据主要包括类上的注解 
 this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);  
//初始化了一个CandidateComponentsIndex(带有缓存 key为类加载器下次使用可以直接去缓存中获取)
//初始化了一个@Componet的index值处理器
 this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader()); } 

总结:ClassPathBeanDefinitionScanner主要初始化了@Component的过滤器,设置了一些环境,加载了resourcePatternResolver、metadataReaderFactory(类元数据工厂)、componentsIndex

2.3register(componentClasses)注册配置类

主要是将new的时候传入的配置类注入到BeanFactory中。

1、调用doRegisterBean除了beanClass之外其他的参数默认都为null

AnnotatedBeanDefinitionReader#doRegisterBean

2、doRegisterBean方法


(1)先创建了一个AnnotatedGenericBeanDefinition

AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);    
// AnnotatedGenericBeanDefinition这个Class主要是GenericBeanDefinition类的子类主要将贴了注解的类通过接口暴漏 AnnotatedBeanDefinition的实现类  这里主要封装了配置类的Class信息(在父类AbstractBeanDefinition中)和类上边的所有注解信息。
// GenericBeanDefinition提供一站式标准的Bean定义,注册 user-visible bean definitions
public AnnotatedGenericBeanDefinition(Class<?> beanClass) {  
	   //调用父类AbstractBeanDefinition. setBeanClass方法 将beanClass复制给成员属性beanClass
    setBeanClass(beanClass);  
	   //创建了一个StandardAnnotationMetadata【标准注解元数据】直接封装在Annotations属性nestedAnnotationsAsMap属性,nestedAnnotationsAsMap属性标记(是否总是返回绑定的注解信息) StandardAnnotationMetadata主要作用就是封装一个类的所有注解
 this.metadata = new StandardAnnotationMetadata(beanClass, true);  

}


(2)、判断配置类上是存在@Conditional条件注解存在话不需要加载

//conditionEvaluator这个是在new AnnotatedBeanDefinitionReader主要用来解析metaData中是否包含@Conditional注解 
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {  
 return;  
} 

(3)、设置一个回调的实例(默认为null)

abd.setInstanceSupplier(instanceSupplier);

(4)、设置一个回调的实例添加到AnnotatedGenericBeanDefinition中。声明指定的工厂方法的替代方法,默认为null

设置类的作用域

//通过scopeMetadataResolver解析配置类属性—>是否是单例、是否使用了代理;默认单例、不是代理
//scopeMetadataResolver是恶汉加载直接new出来new AnnotationScopeMetadataResolver() 
//这个方法主要的作用是找出配置类的作用(不是用代理 单例)
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);  
//获取到作用域设置到配置类的AnnotatedGenericBeanDefinition中
abd.setScope(scopeMetadata.getScopeName());  
4.1)AnnotationScopeMetadataResolver# resolveScopeMetadata 详细说明
 public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {  
   //先创建了一个ScopeMetadata  scope中主要包含scopeName(指定是单例还是原型默认单例)、scopedProxyMode(代理模式枚举包括 DEFAULT【也是NO】、NO【不使用 默认】、INTERFACE【JDK】、TARGET_CLASS【CGLib】)
   ScopeMetadata metadata = new ScopeMetadata();
  // definition就是AnnotatedGenericBeanDefinition 由UML图很明显属于
 if (definition instanceof AnnotatedBeanDefinition) {  
        AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;  
		//主要是获取配置类上是否贴有@Scope注解有的话通过注解的属性来封装值,没有的话直接返回默认的metadata 
        AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(  
                annDef.getMetadata(), this.scopeAnnotationType);  
 if (attributes != null) {  
            metadata.setScopeName(attributes.getString("value"));  
            ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");  
 if (proxyMode == ScopedProxyMode.DEFAULT) {  
                proxyMode = this.defaultProxyMode;  
            }  
            metadata.setScopedProxyMode(proxyMode);  
        }  
    }  
 return metadata;  
} 

(5) 获取到配置类的beanname

主要是通过AnnotationBeanNameGenerator. generateBeanName方法获取到beanName(饿汉创建出来的)

//前边definition = new AnnotatedGenericBeanDefinition(beanClass)  registry就是配置类本身
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {  
 //根据上边的uml可以知道肯定符合
 if (definition instanceof AnnotatedBeanDefinition) {   

		//获取到所有注解上@Component注解的value值@Configurationvalue值存在的话返回这个beanname  
      String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);  
 if (StringUtils.hasText(beanName)) {  
            // Explicit bean name found.  
 return beanName;  
        }  
    }  
    // 不存在构建默认的beanname 类名首字母小写 
 return buildDefaultBeanName(definition, registry);  
}  

(6)处理常用的注解

AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

主要针对@Lazy注解,@Primary注解,@ DependsOn注解,@ Role注解将这些注解的属性值保存在AnnotatedBeanDefinition属性汇中。

(7)qualifiers限定处理,针对@ Primary和@ Lazy进行处理,在初始化配置的时候默认为null。

(8)处理用户自定义的BeanDefinition 在容器启动的时候为null

for (BeanDefinitionCustomizer customizer : definitionCustomizers) {  
    customizer.customize(abd);  
} 

(9)创建一个BeanDefinition持有器,并根据使用的代理模式创建动态代理

//创建一个BeanDefinitionHolder  
// BeanDefinitionHolder 里边只有BeanDefinition和beanName,还有别名,在这里别名没有使用到
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);  
//通过使用的代理模式创建动态代理对象这里没有使用代理
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);  

(10)将初始化好的配置类注入到BeanFactory中

//注册自己传入的主配置类bean定义到容器中  
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); 

//1、先从BeanDefinitionHolder中获取到beanName和BeanDefinition进行注册; 
//2、然后在将别名和beanName进行缓存到调用DefaultListableBeanFactory的父类SimpleAliasRegistry#registerAlias方法将关系维护在aliasMap属性中。【这里没有使用到第二步】

10.1)注册配置类的时候最终调用的是DefaultListableBeanFactory#registerBeanDefinition方法

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)  
 throws BeanDefinitionStoreException {  
    // AnnotatedGenericBeanDefinition是否属于AbstractBeanDefinition 根据上述的UML很明显属于
    //这一步主要校验是否已经注册过了
 if (beanDefinition instanceof AbstractBeanDefinition) {  
 try {  
			//校验是否已经注册过了, 校验是否是beanClass(贴Spring注解的类)是的话是否存在覆盖的方法
            ((AbstractBeanDefinition) beanDefinition).validate();  
        }  
 catch (BeanDefinitionValidationException ex) {  
 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,  
                    "Validation of bean definition failed", ex);  
        }  
    }  
    //从beanDefinitionMap根据BeanName获取是否已经注册了  注意beanDefinitionMap是在 初始化AnnotatedBeanDefinitionReader时候加载的  很明显不存在
    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);  
	//如果existingDefinition不为null的话会进行一系列的判断,判断之后更新下beanDefinitionMap
 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()) {  
                //打印日志  
            }  
        }  
 else if (!beanDefinition.equals(existingDefinition)) {  
 if (logger.isDebugEnabled()) {  
                //打印日志  
            }  
        }  
 else {  
 if (logger.isTraceEnabled()) {  
                //打印日志  
            }  
        }  
 this.beanDefinitionMap.put(beanName, beanDefinition);  
    } 
	// beanDefinitionMap中不存在之心而过else
 else {  
		//再一次通过alreadyCreated判断是否已经创建了,
		//如果已经创建的话更新下beanDefinitionMap 更新beanDefinitionNames(存储的类的全限定名)
 if (hasBeanCreationStarted()) {  
 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;  
 //这个是更新BeanFactory内部单例的名称manualSingletonNames
                removeManualSingletonName(beanName);  
            }  
        }  
 //以上都不满足才会走到这一步 分别添加到beanDefinitionMap、beanDefinitionNames、更新内部单例名称(移除)
 else {  
 this.beanDefinitionMap.put(beanName, beanDefinition);  
 this.beanDefinitionNames.add(beanName);  
            removeManualSingletonName(beanName);  
        }  
 this.frozenBeanDefinitionNames = null;  
    }  
  //这一步主要判断beanName是否已经被实例化到单例池了,如果已经实例化的话直接清除掉(防止多利)
 if (existingDefinition != null || containsSingleton(beanName)) {  
        resetBeanDefinition(beanName);  
    }  
	//判断beanDefinition是否被缓存如果被缓存的话清除缓存
 else if (isConfigurationFrozen()) {  
        clearByTypeCache();  
    }  
}  

总结:register主要的作用是解析了配置了并把配置类的BeanDefinition注册到容器中,注意这个时候还没有实例化,如果被实例化的话会被清除掉。

3.容器准备阶段

3.1 prepareRefresh

准备刷新上下文 ,整体初始化了一些必要的缓存和开关。

protected void prepareRefresh() {  
    // 初始化一些开关
 this.startupDate = System.currentTimeMillis();  
 this.closed.set(false);  
 this.active.set(true);  
   //日志刷新  
 if (logger.isDebugEnabled()) {  
    }  
    // 初始化一些环境属性,可以配置
    initPropertySources();  
    //校验所有被标记为必填的属性不存在抛出异常
    // Validate that all properties marked as required are resolvable:  
    // see ConfigurablePropertyResolver#setRequiredProperties  
    getEnvironment().validateRequiredProperties();  
     //用来缓存早期Application监听器 用于后期直接使用
    // Store pre-refresh ApplicationListeners...  
    //不存在的话创建一个新的LinkedHashSet增删比较多因此用链表的结构
 if (this.earlyApplicationListeners == null) {  
 this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);  
    }  
 else {  //存在的话清空缓存,并把早期的事件监听器加入到缓存中
        // Reset local application listeners to pre-refresh state.  
 this.applicationListeners.clear();  
 this.applicationListeners.addAll(this.earlyApplicationListeners);  
    }  
     //初始化早期事件 
    // Allow for the collection of early ApplicationEvents,  
    // to be published once the multicaster is available...  
 this.earlyApplicationEvents = new LinkedHashSet<>();  
}  

3.2 obtainFreshBeanFactory

创建并刷新BeanFactory,先refresh刷新了BeanFactory,又返回BeanFactory。运用大量的模版设计模式。

在刷新BeanFactory的时候为BeanFactory设置了序列化id来防止弱引用被GC给回收掉。getBeanFactory返回的是之前创建的DefaultListableBeanFactory。

3.3 prepareBeanFactory

beanFactory使用前准备 也就是初始化一些必要的属性。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {     
  //  将classLoader复制给 AbstractBeanFactory. beanClassLoader中 
   beanFactory.setBeanClassLoader(getClassLoader()); 
 //初始化一个StandardBeanExpressionResolver标准的SpringBean表达式解析器存储在beanExpressionResolver属性中。
SpringBean表达式: @Value("#{表达式}")
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
  //初始化一个ResourceEditorRegistrar(属性编辑)资源编辑器注册器,添加到propertyEditorRegistrars属性中
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));  
 
 1.	// 初始化BeanPostProcessor默认类型为ApplicationContextAwareProcessor,里边主要存储了上下文,和    EmbeddedValueResolver解析占位符和表达式的;使用的是默认的BeanFactory来解析的。
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));  
 //忽略环境通知接口,环境通知是被一些Bean实现之后要求在特定环境下进行通知
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);  
   //忽略${}时候通知接口,被一些Object实现当解析嵌入值的时候会进行通知 (比如Spring解析获取 properties)
	   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);  
 //忽略ResourceLoaderAware接口,主要调用getResource()方法来通过资源路径检索外部资源
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);  
 //忽略ApplicationEventPublisherAware接口,比如容器启动或者容器刷新等
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);  
 //忽略MessageSourceAware接口,本地化信息
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);  
 //忽略ApplicationContextAware接口,此接口可以获取到当前spring容器 
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);  
 
    // BeanFactory interface not registered as resolvable type in a plain factory.  
    // MessageSource registered (and found for autowiring) as a bean.  
 //在普通的工厂中,BeanFactory是不能被解析的,因此需要将上边忽略的接口注入放入到缓存中
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);  
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);  
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);  
    beanFactory.registerResolvableDependency(ApplicationContext.class, this); 
 //以上四步主要将对应的Class类型和DefaultListableBeanFactory和AnnotationConfigApplicationContext存储在DefaultListableBeanFactory的resolvableDependencies 属性缓存起来因为在普通的Bean中使用这四种类型的时候是不能直接从IOC容器中获取到的因此这里通过类型+对象的方式缓存起来方便使用!!!也是因为如此才忽略上边的这些接口的。
 
 
 // 向容器中注册早起后置处理器来发现-实现ApplicationListeners接口的监听器 
	  //先查看容器中AbstractBeanFactory.beanPostProcessors属性中是否已经存在,存在的话先清除,对hasDestructionAwareBeanPostProcessors标记为设置为true在加入到beanPostProcessors中 这个标记属性是为了告诉想要注册的BeanPostProcessor已经有DestructionAwareBeanPostProcessors注册了!
    ApplicationListenerDetector作用
     1、在Bean初始化完成之后:如果Bean是单例的则并且实现了ApplicationListener接口。加入到this.applicationListeners中。
     2、在Bean销毁之前搞事情: 如果Bean是一个ApplicationListener,则会从ApplicationEventMulticaster(事件广播器)中提前删除了。
	   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));  
 
    // 判断BeanFactory中是否已经包含了LoadTimeWeaver实例化的bean或者BeanFactory(很明显不包含)
    //LoadTimeWeaver作用AspectJ语言定义切面,在编译期或类加载期将切面织入到Java类中。 织入代码
 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {  
		//如果包括的话会往容器中注入LoadTimeWeaverAwareProcessor后置处理器
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));  
        // 往容器中注入TempClassLoader
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));  
    }  
 
    // 注册默认环境的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());  
    }  
}

总结这一步主要是初始化了classLoader、表达式解析器StandardBeanExpressionResolver、ApplicationListenerDetector、缓存了一个aware、往容器中注入一些BeanFactory。

3.4 postProcessBeanFactory

主要作用是在上下文的子类中对bean factory进行后处理 ,如果单单使用ioc容器的话new AnnotationConfigApplicationContext的话 是没有执行任何的代码的,如果是web应用的话会执行AbstractRefreshableWebApplicationContext#postProcessBeanFactory方法


来查看下这个方法

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {  
   //创建了ServletContextAwareProcessor处理器会注册到DefaultListableBeanFactory的beanPostProcessors属性中,先检查是否存在存在的话先清空,在put
    beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));      
	   //忽略ServletContextAware、ServletConfigAware这两个通知
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);  
    beanFactory.ignoreDependencyInterface(ServletConfigAware.class);  

    //把web应用特殊作用域("request", "session", "globalSession", "application")注册到容器中
	   先把request、session、application放入到AbstractBeanFactory.scopes属性中,又往DefaultListableBeanFactory.resolvableDependencies属性中加入[
{ServletRequest.class, new RequestObjectFactory()},
{ ServletResponse.class, new ResponseObjectFactory()},
{HttpSession.class, new SessionObjectFactory()},
{WebRequest.class, new WebRequestObjectFactory()}]中
    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);  
 
	   //注册Web环境  先调用DefaultSingletonBeanRegistry. registerSingleton方法 把servlet上下文放入单例池。
 beanName= servletContext;Object=ApplicationContextFacade;;在判断是否已经创建了BeanDefinition了,如果创建的话刷新manualSingletonNames属性值,没有创建的话将beanName=servletContext放入到manualSingletonNames属性中  manualSingletonNames属性缓存手动注册单例的名字方便排序  
    WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);  
}  

总结 postProcessBeanFactory这个方法在web应用中主要注入了web应用独有的scope比如request、session等,然后初始化了ServletContext上下文并存放在单例池中,servletContext实例化对象是ApplicationContextFacade

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表