Spring5.0源码深度解析之Spring基于注解启动流程分析🔥

Stella981
• 阅读 757

主要内容:

一、IOC容器的初始化流

  • 创建IOC容器

  • 注册配置类

  • BeanFactory后置处理器

  • Bean的后置处理器

  • 创建Bean对象

IOC容器的初始化流程

从:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);

进入:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { this(); register(annotatedClasses); refresh(); }

一:创建IOC容器

1.this():先执行父类的初始化方法,创建IOC容器

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

2.执行初始化方法创建BeanDefinition读取器和classPath下扫描器

public AnnotationConfigApplicationContext() { this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }

3.this.reader = new AnnotatedBeanDefinitionReader(this)的创建过程:

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); }

4.执行AnnotatedBeanDefinitionReader的构造器:重点在最后一行的注册注解配置处理器

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); //注册注解配置处理器 }

5.1这个方法把下面对象注册到IOC容器里面

Spring5.0源码深度解析之Spring基于注解启动流程分析🔥

5.2ConfigurationClassPostProcessor对象注册的代码

public static Set registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) {

DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);    //创建IOC容器 .... Set beanDefs = new LinkedHashSet<>(4); if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { //注册5.2ConfigurationClassPostProcessor对象到IOC容器中 RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); }

6、执行this.scanner = new ClassPathBeanDefinitionScanner(this);

先走父类

public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters) { this(useDefaultFilters, new StandardEnvironment()); }

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) { this(registry, true); }

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) { this(registry, useDefaultFilters, getOrCreateEnvironment(registry)); }

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) {

Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry;

if (useDefaultFilters) { registerDefaultFilters(); } setEnvironment(environment); setResourceLoader(resourceLoader); }

protected void registerDefaultFilters() { this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { this.includeFilters.add(new AnnotationTypeFilter( ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false)); logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning"); } catch (ClassNotFoundException ex) { // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip. } try { this.includeFilters.add(new AnnotationTypeFilter( ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false)); logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning"); } catch (ClassNotFoundException ex) { // JSR-330 API not available - simply skip. } }

**registerDefaultFilters()把加了@Component注解的的class对象添加到includeFilters**列表

Spring5.0源码深度解析之Spring基于注解启动流程分析🔥

问题1:加了@Component注解的类是怎么注册到SpringIOC容器里面的?

二:注册配置类

1.register(annotatedClasses);把用户指定的类加载到IOC容器里面

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { this(); register(annotatedClasses); refresh(); }

public void register(Class<?>... annotatedClasses) { Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified"); this.reader.register(annotatedClasses); }

2.进入上面创建的reader的注册方法里面

public void register(Class... annotatedClasses) { for (Class annotatedClass : annotatedClasses) { registerBean(annotatedClass); } }

public void registerBean(Class<?> annotatedClass) { doRegisterBean(annotatedClass, null, null, null); }

void doRegisterBean(Class annotatedClass, @Nullable Supplier instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);//创建BeanDefinition对象 if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {    //处理 @Condition注解 return; }

abd.setInstanceSupplier(instanceSupplier); //设置对象是单例模式还是多例模式,默认单例 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); abd.setScope(scopeMetadata.getScopeName());    //获取BeanName,设置的化就采用默认值,否则类名第一个字母小写 String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); //处理Lazy,primary等注解  .....

BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//判断对象是否需要代理,不需要直接返回,需要的化,重新创建BeanDefinition加入代理的信息 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);    //注册配置类到IOC容器 }

3、调用shouldSkip()处理**@Condition**注解

public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) { if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) { //如果没有不是@Condition注解直接返回fasle return false; } if (phase == null) { //下面递归调用本方法 if (metadata instanceof AnnotationMetadata && ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) { return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION); } return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN); } List conditions = new ArrayList<>(); for (String[] conditionClasses : getConditionClasses(metadata)) { //phase不为空的时候,执行所有condition类的match方法。 for (String conditionClass : conditionClasses) { Condition condition = getCondition(conditionClass, this.context.getClassLoader()); conditions.add(condition); } }     .... return false; }

4、调用processCommonDefinitionAnnotations处理下面的的注解

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) { AnnotationAttributes lazy = attributesFor(metadata, Lazy.class); if (lazy != null) { abd.setLazyInit(lazy.getBoolean("value")); } else if (abd.getMetadata() != metadata) { lazy = attributesFor(abd.getMetadata(), Lazy.class); if (lazy != null) { abd.setLazyInit(lazy.getBoolean("value")); } } if (metadata.isAnnotated(Primary.class.getName())) { abd.setPrimary(true); } AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class); if (dependsOn != null) { abd.setDependsOn(dependsOn.getStringArray("value")); }

if (abd instanceof AbstractBeanDefinition) { AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd; AnnotationAttributes role = attributesFor(metadata, Role.class); if (role != null) { absBd.setRole(role.getNumber("value").intValue()); } AnnotationAttributes description = attributesFor(metadata, Description.class); if (description != null) { absBd.setDescription(description.getString("value")); } } }

三、BeanFactory后置处理器 1、beanFactory后置处理器(以ConfigurationClassPostProcessor为例)

1.1、ConfigurationClassPostProcessor继承关系

Spring5.0源码深度解析之Spring基于注解启动流程分析🔥

1.2、接口说明

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; }

public interface BeanFactoryPostProcessor { void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }

2、refresh()->invokeBeanFactoryPostProcessors方法执行beanFactory后置处理器

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }

public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {

//2.1.1、执行IOC容器beanFactoryPostProcessors列表里面存在的BeanDefinitionRegistryPostProcessor处理器    //2.1.2、把实现了BeanDefinitionRegistryPostProcessor接口的对象放到registryPostProcessors列表    //2.1.3、把只实现BeanFactoryPostProcessor接口的放到regularPostProcessors Set processedBeans = new HashSet<>();

if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List regularPostProcessors = new LinkedList<>(); List registryPostProcessors = new LinkedList<>();

  for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
     if (postProcessor instanceof **BeanDefinitionRegistryPostProcessor**) {
        BeanDefinitionRegistryPostProcessor registryPostProcessor =
              (BeanDefinitionRegistryPostProcessor) postProcessor;
        registryPostProcessor.**postProcessBeanDefinitionRegistry**(registry);
        **registryPostProcessors**.add(registryPostProcessor);
     }
     else {
        **regularPostProcessors**.add(postProcessor);
     }
  }

      //2.2、获取所有注册到IOC容器里面的BeanDefinitionRegistryPostProcessor对象的beanName String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);       //2.3、按照一定的顺序执行postProcessBeanDefinitionRegistry方法,并且放到registryPostProcessors列表 List priorityOrderedPostProcessors = new ArrayList<>();     ....

else { invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); }     //2.4、获取所有BeanFactoryPostProcessor对象并且执行postProcessBeanFactory方法 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); .... }

3、ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法

@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {     .... processConfigBeanDefinitions(registry); }

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {      //注册BeanDefinitions this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); }

Spring5.0源码深度解析之Spring基于注解启动流程分析🔥

Spring5.0源码深度解析之Spring基于注解启动流程分析🔥

四、注册Bean的后置处理器:registerBeanPostProcessors(beanFactory);

1、注册bean后置处理器到IOC并且创建对象

public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

....     //根据实现的额接口不同,放入到不同的列表里面 List priorityOrderedPostProcessors = new ArrayList<>(); List internalPostProcessors = new ArrayList<>(); List orderedPostProcessorNames = new ArrayList<>(); List nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {            //创建Bean BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); ....

.... }

五、创建Bean对象

1、refresh()->finishBeanFactoryInitialization()->preInstantiateSingletons()

// Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory);

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { .... // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); }

@Override public void preInstantiateSingletons() throws BeansException { if (this.logger.isDebugEnabled()) { this.logger.debug("Pre-instantiating singletons in " + this); } List beanNames = new ArrayList<>(this.beanDefinitionNames); for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);//是否创建对象 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) {//是否是FactoryBean,是则调用getObject()方法 final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName); boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction) () -> ((SmartFactoryBean) factory).isEagerInit(), getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } else { getBean(beanName); } } }

2、getBean(beanName)方法核心步骤

@Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }

下面几个关键的方法需要分析下getSingleton,createBean 和 getObjectForBeanInstance

protected T doGetBean(final String name, @Nullable final Class requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

final String beanName = transformedBeanName(name); Object bean;

// Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { .... bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);//从Bean的实例中获取对象 }

else { .... // Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }

     else if (mbd.isPrototype()) {
        // It's a prototype -> create a new instance.
        Object prototypeInstance = null;
        try {
           beforePrototypeCreation(beanName);
           prototypeInstance = createBean(beanName, mbd, args);
        }
        finally {
           afterPrototypeCreation(beanName);
        }
        bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
     }

     else {
        String scopeName = mbd.getScope();
        final Scope scope = this.scopes.get(scopeName);
        if (scope == null) {
           throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
        }
        try {
           Object scopedInstance = scope.get(beanName, () -> {
              beforePrototypeCreation(beanName);
              try {
                 return createBean(beanName, mbd, args);
              }
              finally {
                 afterPrototypeCreation(beanName);
              }
           });
           bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
        }
       ....

} .... return (T) bean; }

getSingleton方法执行流程【缓存中获取单例bean】

bean的加载过程。单例bean在spring容器中只会被创建一次,后续再获取Bean直接从单例缓存中获取,当然这里也只是尝试加载,首先尝试从缓存中加载,然后再次尝试从singletonFactories中加载。

因为在创建单例bean 的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,spring创建bean的原则是不等bean创建完成就会将创建的bean的ObjectFactory提早曝光加入到缓存中,

一旦下一个bean创建时需要 依赖上一个Bean,则直接使用ObjectFactory。

public Object getSingleton(String beanName) { return getSingleton(beanName, true);//参数true设置标识允许早期依赖 }

protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName);//检查缓存中是否存在实例 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {//如果为空 synchronized (this.singletonObjects) {//如果为空,则锁定全局变量进行处理 singletonObject = this.earlySingletonObjects.get(beanName);//如果此bean正在加载,则不会处理后面逻辑 if (singletonObject == null && allowEarlyReference) {//当某些方法需要提前初始化的时候 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject();//调用预先设定的getObject方法,创建bean this.earlySingletonObjects.put(beanName, singletonObject);//记录在缓存中earlySingletonObjects和singletonFactories互斥 this.singletonFactories.remove(beanName); } } } } return singletonObject; }

private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); private final Set registeredSingletons = new LinkedHashSet<>(256);

Spring5.0源码深度解析之Spring基于注解启动流程分析🔥

  • singletonObjects:用于保存BeanName和创建Bean实例之间的关系,bean name->bean instance
  • singletonFactories:用于保存BeanName和创建bean工厂之间的关系,bean name->ObjectFactory
  • earlySingletonObjects:也是保存BeanName和创建Bean实例之间的关系,与singletonObjects不同在于,当一个单例bean被放到这里面后,那么当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是为了检测循环引用。
  • registeredSingletons:用来保存当前所有已注册的Bean

getObjectForBeanInstance方法执行流程

在getBean方法中,getObjectForBeanInstance是个高频率使用的方法,无论是从缓存中获取bean还是根据不同的scope策略加载bean。总之我们得到Bean的实例后要做的第一步就是调用这个方法来检测当前Bean是否是FactoryBean类型

如果是,那么需要调用该Bean对应 的FactoryBean实例中的getObject()作为返回值。

无论是从缓存中获取到Bean还是通过不同的scope策略加载的Bean都只是最原始的Bean状态,并不一定是我们想要的Bean。

举个例子:假如我们需要对工厂Bean进行处理,那么这里得到的是工厂Bean的初始状态,但是我们正真需要的是工厂Bean中定义的factory-method方法中返回的Bean,而getObjectForBeanInstance方法就是完成这个工作的。

下面来分析下getObjectForBeanInstance这个方法:

protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

// 如果指定的name是工厂相关(以&为前缀)且BeanInstance又不是FactoryBean类型则验证不通过 if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); }

// 现在我们有了这个Bean实例,这个实例可能会是正常的Bean或者FactoryBean // 如果是FactoryBean我们使用它创建实例,但是如果用户想要直接获取工厂实例而不是工厂的getObject方法对应的实例,那么传入的name应该加入前缀& if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; }    //加载FactoryBean Object object = null; if (mbd == null) {       //尝试从缓存中加载Bean object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // 到这块已经明确了beanInstance一定是FactoryBean类型 FactoryBean factory = (FactoryBean) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); }       //是否是用户定义的而不是应用程序本身定义的 boolean synthetic = (mbd != null && mbd.isSynthetic()); object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }

从上面代码来看,大多是些辅助代码以及一些功能性的判断,而正真的核心委托给getObjectFromFactoryBean,****我们来看看这个方法:

这个方法里面只做了一件事情,就是返回的Bean如果是单例,那么就必须要保证全局唯一,同时也因为是单例的,所以不必重复创建,可以使用缓存来提高性能,

也就是说,以及加载过就要记录下来以便于下次复用,否则的化就直接获取了。

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { if (factory.isSingleton() && containsSingleton(beanName)) {//如果是单例模式 synchronized (getSingletonMutex()) {//锁住全局变量 Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { object = doGetObjectFromFactoryBean(factory, beanName); //缓存中获取bean Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { if (shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex); } } this.factoryBeanObjectCache.put(beanName, object); } } return object; } } else { Object object = doGetObjectFromFactoryBean(factory, beanName);//执行这个方法,会去调用getObject方法 if (shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName);//调用ObjectFactory的后处理器 } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } return object; } }

下面看下:doGetObjectFromFactoryBean方法:

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) throws BeanCreationException {

Object object; try { if (System.getSecurityManager() != null) {//需要权限验证 AccessControlContext acc = getAccessControlContext(); try { object = AccessController.doPrivileged((PrivilegedExceptionAction) () -> factory.getObject(), acc); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { object = factory.getObject();//直接调用getObject方法 } } ... return object; }

上面我们已经讲述了FactoryBean的调用方法,如果Bean声明为FactoryBean类型,则当提取Bean的时候取到的并不是FactoryBean而是FactoryBean中对应的getObject方法返回的Bean,

而****doGetObjectFromFactoryBean正是实现了这个功能的。但是我们看到了上面的方法中除了调用object = factory.getObject()得到我们想要的结果后并没有直接返回,而是接下来又调用

postProcessObjectFromFactoryBean来做后置处理,我们进入这个后置处理方法,看看:

Spring5.0源码深度解析之Spring基于注解启动流程分析🔥

protected Object postProcessObjectFromFactoryBean(Object object, String beanName) { return applyBeanPostProcessorsAfterInitialization(object, beanName); }

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {

Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { Object current = beanProcessor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }

对于后置处理器的使用,后续会讲解到,这里我们需要明确一点:在Spring中获取Bean的规则中有一条:尽可能保证所有的Bean初始化后都会调用注册的

BeanPostProcessor的****postProcessAfterInitialization方法进行处理,在实际开发中大可以争对此特性设计自己的业务逻辑。

获取单例:

// Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }

如果缓存不存在已经加载的单例Bean,就需要从头开始Bean的加载过程,而Spring中使用了getSingleton的重载方法实现Bean的加载过程
进入getSingleton方法

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } }

protected void beforeSingletonCreation(String beanName) { if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {//将当前需要创建的Bean记录在缓存中,这样可以对循环依赖进行检测 throw new BeanCurrentlyInCreationException(beanName); } }

protected void afterSingletonCreation(String beanName) { if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {//当Bean加载结束后需要移除缓存中对该Bean的正在加载状态的记录 throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); } }

返回处理结果

虽然我们已经从外部了解到了加载Bean的逻辑架构,但现在我们还并没有开始对Bean加载功能的探索,之前提到过,Bean的加载逻辑其实是在传入的ObjectFactory类型的参数singletonFactory中定义的,

我们反推参数的获取,得到如下的代码:

sharedInstance = getSingleton(beanName,new ObjectFactory() { public Object getObject() throws BeansException{         try{              return createBean(beanName, mbd, args);         }catch(BeansException ex){             destroySingleton(beanName);             throw ex;         }       } })

ObjectFactory的核心部分其实只是调用了createBean的方法,所以我们还需要到createBean方法中寻找真理!

准备创建Bean [createBean方法执行流程]

@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { .... try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; .... }

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {

.... try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } ..... }

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean);//执行aware接口相关方法 }

Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);//Bean后置处理器的前置方法 }

try { invokeInitMethods(beanName, wrappedBean, mbd);//执行初始化的方法 } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//Bean后置处理器的后置方法 }

return wrappedBean; }

此方法中最吸引我们的无疑是两个方法:applyBeanPostProcessorsBeforeInitialization以及applyBeanPostProcessorsAfterInitialization。****这两个方法是实现非常简单,

无非是对后处理器中的所有 InstantiationAwareBeanPostProcessor类型的后置处理器BeanPostProcessor进行postProcessBeforeInitialization方法和postProcessAfterInitialization方法的调用

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {

Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { Object current = beanProcessor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {

Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { Object current = beanProcessor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }

根据上面代码可知:Bean的实例化前调用,也就是将AbstractBeanDefinition转换为BeanWrapper前的处理。给子类一个修改BeanDefinition的机会,也就是说当程序经过这个方法后,

Bean可能已经不是我们认为的Bean了,而是经过代理后的Bean,可能是CGLIB生成的,也可能是通过其它技术生成的。后面会分析到。

到这里,结束创建单例的对象

Spring5.0源码深度解析之Spring基于注解启动流程分析🔥

Spring5.0源码深度解析之Spring基于注解启动流程分析🔥

SpringBean的生命周期总结

源码分析流程:

1、执行refresh()刷新方法

2、finishBeanFactoryInitialization(beanFactory);

3、beanFactory.preInstantiateSingletons();

4、getBean(beanName)->doGetBean()->createBean()->doCreateBean()->createBeanInstance()初始化对象(默认情况下使用Java反射机制初始化对象,也可以通过CGLIB)

5、initializeBean()

6、invokeAwareMethods()判断是否有Aware接口依赖信息

7、applyBeanPostProcessorsBeforeInitialization()执行前置处理

8、invokeInitMethods()执行init()方法

8、applyBeanPostProcessorsAfterInitialization()执行后置处理

本文参考:

书籍:Spring源码深度解析

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这