Spring源码剖析(一) bean的生命周期

文章目录

        • spring bean的产生过程
        • 源码分析
          • 生命周期步骤
          • 解决循环依赖的三级缓存
          • 三级缓存调用顺序
          • 当单例对象含有原型属性
          • FactoryBean与beanFactory
          • 动态注入Springboot

spring bean的产生过程

class-----beanDeefinition-----object(bean)

classLoader
扫描注解
放入一个map中
正常下
BeanFactoryPostProcessor扩展
java文件
字节码文件
BeanDefinition对象
map
出来对象放入单例池map中-私有的
map传入给这个扩展中更改BeanDefinition对象
// 初始化spring容器
// BeanDefinition是通过扫描出来的, Appconfig是个bean,因此需要先注册Appconfig,然后根据Appconfig的bd去扫描
AnnotationConfigApplicationContext ac = new 
AnnotationConfigApplicationContext(Appconfig.class);
// 初始化的过程如下
// 1. 扫描注解
// 2. 解析类结构
	for() {
        GenericBeanDefinition g = new GenericBeanDefinition();
        g.setBeanClass(XXx.class);
        g.setBeanClassName("xxx名字");
        g.setScope("prototype");
        //***
        map.put("xxx名字", g);
        beanNames.add("xxx名字");
    }
// 3. 遍历map 数据校验成功后new单例 对象放入单例池(singletonObjects)
	beanNames.for(){
        GenericBeanDefinition g = map.get("beanName")
        // 不是抽象&&是单列&&不是懒加载
    }
// 可通过ac.getBeanDefinitionXXX去查看

//tips:
1. 项目中的class 通过AnnotateBeanDefinitionReader转换成一个BD,前提是加了注解。

通过BeanFactoryPostProcessor扩展

这里呢实际是在createBean时调用了initializeBean方法,里面调用了before和after, 类似自定义的,或者PostConstror都是实现了这个后置处理器

// 修改注入的IndexService为UserService
@Component
public class CustomBeanFactoryPostProcessor impl BeanFactoryPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("beanName"+beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("After beanName"+beanName);
        return bean;
    }
}

单例池中,spring会在开始时创建一些对象,其余正常对象都是通过BeanDefinition生成放入单例池中

源码分析

  • 入口

    public AnnotationConfigApplicationContext(Class... componentClasses) {
        	// 注册了6个bd(我看5.2.8版本没有RequiredAnnotationBeanPostProcessor),其中包含ConfigurationClassPostProcessor.class
            this.reader = new AnnotatedBeanDefinitionReader(this);
    		this.scanner = new ClassPathBeanDefinitionScanner(this);
        	// 注册启动时的class
            this.register(componentClasses);
            this.refresh();
        }
    
  • register注册机制

    public void register(Class... componentClasses) {
            Assert.notEmpty(componentClasses, "At least one component class must be specified");
        // 通过一个reader把class转换成一个bd并注入到DefaultListableBeanFactory的beanDefinitionMap中
            this.reader.register(componentClasses);
    }
    
  1. refresh机制 进入 AbstractApplicationContext
 public void refresh() throws BeansException, IllegalStateException {
     //设置启动时间,是否激活标志位,初始化加载资源
     this.prepareRefresh();
     // 获取beanDefinition
     // 父类DefaultListableBeanFactory 
     // 含有Map beanDefinitionMap
     ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
     // 加载一些初始的对象到工厂中,并忽略一些接口
     this.prepareBeanFactory(beanFactory);
     try{
         // 暂为空
         this.postProcessBeanFactory(beanFactory);
       // 设置执行自定义的ProcessBeanFactory和spring内部自定义的(ConfigurationClassPostProcessor)这里是手动给spring的,就是addResigster(XX)注册的
         /*
         这个函数完成了解析@Configuration开始,扫描子包,将所有的可扫描的类转为bd
         后续详解
         */
         this.invokeBeanFactoryPostProcessors(beanFactory);
         this.registerBeanPostProcessors(beanFactory);
         this.initMessageSource();
         this.initApplicationEventMulticaster();
         this.onRefresh();
         this.registerListeners();
         // 这一步是进行初始化和完成生命周期
         this.finishBeanFactoryInitialization(beanFactory);
         this.finishRefresh();
     }
 }
  1. 进入 AbstractApplicationContextfinishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // ....
    beanFactory.preInstantiateSingletons();
 }
  1. 进入的是DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
public void preInstantiateSingletons() throws BeansException {
    List<String> beanNames = new ArrayList(this.beanDefinitionNames);
    Iterator var2 = beanNames.iterator();
    while(true) {
        String beanName;
        Object bean;
        do {
            while(true) {
                RootBeanDefinition bd;
                do {
                    do {
                        do {
                            if (!var2.hasNext()) {
                                var2 = beanNames.iterator();
                                while(var2.hasNext()) {
                                    beanName = (String)var2.next();
                                    // [1]!!!这里是取数据的地方!!!
                                    Object singletonInstance = this.getSingleton(beanName);
                                    if (singletonInstance instanceof SmartInitializingSingleton) {
                                        SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
                                        if (System.getSecurityManager() != null) {
                                            AccessController.doPrivileged(() -> {
                                                smartSingleton.afterSingletonsInstantiated();
                                                return null;
                                            }, this.getAccessControlContext());
                                        } else {
                                            smartSingleton.afterSingletonsInstantiated();
                                        }
                                    }
                                }

                                return;
                            }

                            beanName = (String)var2.next();
                            bd = this.getMergedLocalBeanDefinition(beanName);
                        } while(bd.isAbstract());
                    } while(!bd.isSingleton());
                } while(bd.isLazyInit());

                if (this.isFactoryBean(beanName)) {
                    bean = this.getBean("&" + beanName);
                    break;
                }
                // 这一句是亮点
                this.getBean(beanName);
            }
        } while(!(bean instanceof FactoryBean));
    }
}
  1. AbstractBeanFactory.getBean()会调用AbstractBeanFactory.doGetBean()这里是亮点
 protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
     // 校验bean名,transformedBeanName(name)这里的name就是bean的名字
     String beanName = this.transformedBeanName(name);
     // 剖析1:检查单例池中是否已经存在,避免重复定义
     Object sharedInstance = this.getSingleton(beanName);
     // 定义了一个对象,用来存将来返回出来的bean
     Object bean;
     if (sharedInstance != null && args == null) {
         // 剖析2 暂时理解为没啥意义 bean = sharedInstance
         bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
     } else {
         // 剖析3 这是个[正在创建的原型集合] 除非有原型对象循环注入会报错,正常情况不会进入的
         if (this.isPrototypeCurrentlyInCreation(beanName)) {
             throw new BeanCurrentlyInCreationException(beanName);
         } else{
      	// 剖析4 这里是创建bean的地方
      	if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  return createBean(beanName, mbd, args);
               }
               catch (BeansException ex) {
                  destroySingleton(beanName);
                  throw ex;
               }
            });
        }
     }

 }
  1. DefaultSingletonBeanRegistry.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!)");
              }
              this.beforeSingletonCreation(beanName);
              boolean newSingleton = false;
              boolean recordSuppressedExceptions = this.suppressedExceptions == null;
              if (recordSuppressedExceptions) {
                  this.suppressedExceptions = new LinkedHashSet();
              }

              try {
                  // 就是调用上面传来的lamda表达式(一个构建工厂)
                  singletonObject = singletonFactory.getObject();
                  newSingleton = true;
              } finally {
                  if (recordSuppressedExceptions) {
                      this.suppressedExceptions = null;
                  }

                  this.afterSingletonCreation(beanName);
              }

              if (newSingleton) {
                  this.addSingleton(beanName, singletonObject);
              }
          }

          return singletonObject;
      }
  }
  1. AbstractAutowireCapableBeanFactory.createBean()
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        RootBeanDefinition mbdToUse = mbd;
        Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        try {
            mbdToUse.prepareMethodOverrides();
        }
        Object beanInstance;
        try {
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
            if (beanInstance != null) {
                return beanInstance;
            }
        } 
        try {
            beanInstance = this.doCreateBean(beanName, mbdToUse, args);
            return beanInstance;
        } 
    }
  1. [创建对象]AbstractAutowireCapableBeanFactory.createBean()-> doCreateBean()
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if (instanceWrapper == null) {
            // 创建了对象 调用了构造方法
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                mbd.postProcessed = true;
            }
        }

        boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            // 插入二级缓存中(工厂)
            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }

        Object exposedObject = bean;

        try {
            this.populateBean(beanName, mbd, instanceWrapper);
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        }
        if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                }
            }
        }

        try {
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        }
    }
  1. 进入AbstractAutowireCapableBeanFactory.initializeBean()
 protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(() -> {
                this.invokeAwareMethods(beanName, bean);
                return null;
            }, this.getAccessControlContext());
        } else {
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            // 执行了BeanPostProcessor的before
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            // 执行InitializingBean初始化就是实现了InitializingBean接口,执行其自定义初始化的方法,目测源码都是无参的方法
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        }
     // 执行了BeanPostProcessor的after
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }
  1. [调用@PostContructor]以及BeanPostProcessor进入 AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization()
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;

        Object current;
        for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
            BeanPostProcessor processor = (BeanPostProcessor)var4.next();
            // 这里调用了BeanPostProcessor
            current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
        }
        return result;
    }
生命周期步骤
  1. 先构造对象 调用对象的构造函数instanceWrapper

  2. 判断循环依赖

  3. 注入类中的其他属性

  4. 生命周期初始化方法(执行顺序 先->后)

    1. @PostConstruct

    2. 继承InitializingBean 实现 afterPropertiesSet()

      @Component
      class XXXX implements InitializingBean {
          @Override
          public void afterPropertiesSet() throws Exception {
              // 初始化
          }
      }
      
    3. xml配置

      <bean id="" class="" init-method="init">
      	<property name="" ref=""/>
      bean>
      
      class XXX{
          public void init() {
              // 初始化操作
          }
      }
      
  5. 执行AOP

    被代理的对象名字形如 , 例 如 ‘ S e r v i c e ,例如`Service ServiceEnhancerBySpringCGLIB$$地址`

  6. 放进一级缓存单例池中

解决循环依赖的三级缓存
  1. Map singletonObjects一级缓存,单例池,缓存Bean

    该缓存是存放完成生命周期对象的bean

  2. Map> singletonFactories二级缓存,缓存创建对象的工厂

    该缓存时存放创建对象的工厂,当有AOP时,该工厂在注入其他属性时(bean),可以将AOP步骤提前到这一步,保证AOP的正确

  3. Map earlySingletonObjects三级缓存,缓存工厂创建的对象

    该步骤是存放二级缓存创建的对象,由于二级缓存创建可能较为复杂,所有需要三级缓存,并且二级缓存可能占内存较大且较为复杂,插入三级缓存后应清除掉二级缓存

三级缓存调用顺序

在 preInstantiateSingletons中[1],调用 getSingleton(beanName)

  • 顺序是,一级缓存->三级缓存->二级缓存
 @Nullable
    public Object getSingleton(String beanName) {
        return this.getSingleton(beanName, true);
    }

    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 一级缓存中取
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            synchronized(this.singletonObjects) {
                // 从三级缓存中取
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    // 从二级缓存中取
                    ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        // 创建对象
                        singletonObject = singletonFactory.getObject();
                        // 放入三级缓存
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        // 从二级缓存中移除
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }

        return singletonObject;
    }
当单例对象含有原型属性

spring默认 单例每次调用原型对象不会每次产生一个新对象,因为,spring对单例对象只注入一次。为了达到每次都是不同对象,可以参考以下两种方法:

  1. 继承ApplicationContextAware

    @Component("index")
    @Scope("prototype")
    public class IndexComponent {
        public void test(){
            System.out.println("IndexComponent-prototype");
        }
    }
    
    @Service
    public class TestService implements ApplicationContextAware {
        private ApplicationContext applicationContext;
        private IndexComponent indexComponent;
    
        public void setIndex(){
            indexComponent = (IndexComponent) this.applicationContext.getBean("index");
            System.out.println("print:"+indexComponent.hashCode());
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    }
    
    // 实际调用
    AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
            // 设置XML配置
            ac.register(ApplicationConfig.class);
            ac.refresh();
            TestService us = (TestService) ac.getBean("testService");
            us.setIndex();//print:1545242146
            us.setIndex();//print:1524126153
            us.setIndex();//print:102065302
    
  2. 使用注解@Lookup

    @Service
    public abstract class TestService {
        private ApplicationContext applicationContext;
        private IndexComponent indexComponent;
    
        // 这里就是抽象方法 按文档来的,可行
        @Lookup
        public abstract IndexComponent getIndexComponent();
    
        public void getIndex(){
            indexComponent = getIndexComponent();
            System.out.println("print:"+indexComponent.hashCode());
        }
    }
    
FactoryBean与beanFactory
  • FactoryBean是一个接口,我们可以用它来实例化一个spring的bean。目的是隐藏掉复杂的bean的实现过程,其自身也是个bean,是一种通过bean创建bean的方式。他可以实现类似装饰模式,工厂模式。

    public interface FactoryBean<T> {
        String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
    
        @Nullable
        T getObject() throws Exception;
    
        @Nullable
        Class<?> getObjectType();
    
        default boolean isSingleton() {
            return true;
        }
    }
    
    // 目标对象
    public class ManComponent {
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void speakName() {
            System.out.println("ManComponent:"+name);
        }
    }
    
    // 将目标对象注入Spring中
    @Component("manBoy")
    public class ManFactoryBean implements FactoryBean {
        @Override
        public Object getObject() throws Exception {
            ManComponent man = new ManComponent();
            man.setName("Little Pig");
            return man;
        }
    
        @Override
        public Class<?> getObjectType() {
            return ManComponent.class;
        }
    
        @Override
        public boolean isSingleton() {
            return true;
        }
    }
    // 实际调用
    AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
    // 设置XML配置
    ac.register(ApplicationConfig.class);
    ac.refresh();
    // 获得生成的bean对象
    ManComponent man = (ManComponent) ac.getBean("manBoy");
    // 获得factoryBean 加&符号
    ManFactoryBean manfactory = (ManFactoryBean) ac.getBean("&manBoy");
    man.speakName();
    
  • BeanFactory负责生产和管理bean的一个工厂。他是Spring IOC容器的核心接口,他负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。由于他只是一个接口,不是IOC容器的具体实现,因此Spring中有许多继承他的子接口去扩展IOC的功能。

  • BeanFactory和ApplicationContext就是spring框架的两个IOC容器,现在一般使用ApplicationnContext,其不但包含了BeanFactory的作用,同时还进行更多的扩展。

  • BeanFacotry是spring中比较原始的Factory,原始的BeanFactory无法支持spring的许多插件

    public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
        @Nullable
        String getId();
    
        String getApplicationName();
    
        String getDisplayName();
    
        long getStartupDate();
    
        @Nullable
        ApplicationContext getParent();
    
        AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
    }
    
    public interface BeanFactory {
        String FACTORY_BEAN_PREFIX = "&";
    
        Object getBean(String var1) throws BeansException;
    
        <T> T getBean(String var1, Class<T> var2) throws BeansException;
    
        Object getBean(String var1, Object... var2) throws BeansException;
    
        <T> T getBean(Class<T> var1) throws BeansException;
    
        <T> T getBean(Class<T> var1, Object... var2) throws BeansException;
    
        <T> ObjectProvider<T> getBeanProvider(Class<T> var1);
    
        <T> ObjectProvider<T> getBeanProvider(ResolvableType var1);
    
        boolean containsBean(String var1);
    
        boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
    
        boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;
    
        boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;
    
        boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;
    
        @Nullable
        Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
    
        @Nullable
        Class<?> getType(String var1, boolean var2) throws NoSuchBeanDefinitionException;
    
        String[] getAliases(String var1);
    }
    
    动态注入Springboot

    近期有个需求,需要动态编译,再加入Springboot的IOC容器中

      // 获取bean工厂并转换为DefaultListableBeanFactory
            DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) ctx.getBeanFactory();
    
            // 通过BeanDefinitionBuilder创建bean定义(BD)
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(tarClazz);
    
            // 注册进SpringBoot容器中,还是走那一套生命周期函数
            defaultListableBeanFactory.registerBeanDefinition("hoComponent", beanDefinitionBuilder.getRawBeanDefinition());
    

你可能感兴趣的:(JAVA,SpringBoot,经典问题解析,spring,java)