Spring原理篇(6)--为什么你跟别的程序员一起去面试.同样问的Spring的原理;别人可以拿30K 你却只能要到15K;前面三章文章的铺垫,为的就是现在<Spring真正的生命周期-下>

@TOC# Spring系列
记录在程序走的每一步___auth:huf


拨开云雾见天日 守得云开见月明

Spring 真正的生命周期;

我们接着上一篇文章 最后阐述的地方 进行承接:

我们在初始化Bean之前要实例化Bean 实例化就是根据Bean的构造函数 进行创建;通过doGetBean
进行创建; 这里又分了几个PostPorcessor 分别是 : InstantiationAwareBeanPostProcessor 还有 MergedBeanDefinitionPostProcessor 有些喜欢细节的同学 会揪着 到底是在哪创建了Bean; 一笔带过了通过doGetBean 创建Bean这里源码并没有贴出来; 这里 我就带大伙 再次进入 doGetBean 里面 是怎么创建出Bean 的;
1:在doGetBean 点进去之后;

	@SuppressWarnings("unchecked")
	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
    
    
			
---------------		省过部分代码
					 看重点代码;再单例池中去找到这个Bean  
					sharedInstance = getSingleton(beanName, () -> {
    
    
						try {
    
    
							如果找不到 就会创建这个Bean;
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
    
    
							destroySingleton(beanName);
							throw ex;
						}
					});
					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
---------------		省过部分代码
			try {
    
    
						Object scopedInstance = scope.get(beanName, () -> {
    
    
							初始化前
							beforePrototypeCreation(beanName);
							try {
    
    
								初始化
								return createBean(beanName, mbd, args);
							}
							finally {
    
    
								初始化后
								afterPrototypeCreation(beanName);
							}
						});

	}

在createBean 方法中:

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

		if (logger.isTraceEnabled()) {
    
    
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		...
		RootBeanDefinition mbdToUse = mbd;
		确保bean类在这一点上被实际解析,并且
		在动态解析类的情况下克隆bean定义
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    
    
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
		准备方法重写
		try {
    
    
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
    
    
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}
		try {
    
    
			允许BeanPostProcessors有机会返回代理而不是目标bean实例-这里能明白的同学可以加分了;
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
    
    
				return bean;
			}
		}
		catch (Throwable ex) {
    
    
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}
		try {
    
    
			调用方法是 doCreateBean  跟CreateBean 方法 是两个方法;重点 重点 重点
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
    
    
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			接下来直接返回实例; 不用多说;
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
    
    
			throw ex;
		}
		catch (Throwable ex) {
    
    
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

doCreateBean

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
    
    
		开始实例化Bean
		BeanWrapper instanceWrapper = null;
		判断Bean是不是单例的 如果是
		if (mbd.isSingleton()) {
    
    
			先从Factory 删除Bean; 这里 就是个ConcurrentMap 也就是删除正在创建的Bean的包装对象;
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		删除了之后 是不是null;  然后开始createBeanInstance
		if (instanceWrapper == null) {
    
    
			开始进入createBeanInstance
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		以下源码暂时不解析;  在之后的篇章会详细说的; 目前就到这里可以了

进入createBeanInstance 方法内 不用纠结每一行代码;不然会彻底迷失在Spring源码中;

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    
    
		确保bean class 这里过; 
		Class<?> beanClass = resolveBeanClass(mbd, beanName);
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
    
    
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
    
    
			return obtainFromSupplier(instanceSupplier, beanName);
		}
		if (mbd.getFactoryMethodName() != null) {
    
    
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}
		重新创建同一bean时的快捷方式
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
    
    
			synchronized (mbd.constructorArgumentLock) {
    
    
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
    
    
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
    
    
			if (autowireNecessary) {
    
    
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
    
    
				return instantiateBean(beanName, mbd);
			}
		}

		获取目前传入的Bean的构造器 确定Bean使用的是什么构造器; 如果没有指定构造器 那么就是无参构造器;
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
    
    
			return autowireConstructor(beanName, mbd, ctors, args);
		}
		确定构造器的阶段;
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
    
    
			return autowireConstructor(beanName, mbd, ctors, null);
		}
		这一行代码是重点;  没有特殊处理 那么就用无参的 这里进来;
		return instantiateBean(beanName, mbd);
	}

instantiateBean

	protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
    
    
	传入的BeanNameRootBeanDefinition 最后 在 instantiate 中 被执行;
		try {
    
    
			Object beanInstance;
			if (System.getSecurityManager() != null) {
    
    
				beanInstance = AccessController.doPrivileged(
						(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
						getAccessControlContext());
			}
			else {
    
    
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
    
    
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

instantiate

@Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    
    
		if (!bd.hasMethodOverrides()) {
    
    
			构造方法; 
			Constructor<?> constructorToUse;
			加锁
			synchronized (bd.constructorArgumentLock) {
    
    
				获取构造对象 赋值
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				判断构造对象  主要是判断; 下面的BeanUtils 那一句 才是重点;
				if (constructorToUse == null) {
    
    
					final Class<?> clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
    
    
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
    
    
						if (System.getSecurityManager() != null) {
    
    
							constructorToUse = AccessController.doPrivileged(
									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
						}
						else {
    
    
							constructorToUse = clazz.getDeclaredConstructor();
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
    
    
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			这里是重点 instantiateClass
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
    
    
			cglib的东西 不管; 后面再说;
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

instantiateClass

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
    
    
		这里大家应该都可以看懂了; 传进构造函数; 判空
		Assert.notNull(ctor, "Constructor must not be null");
		try {
    
    
			ReflectionUtils.makeAccessible(ctor);
			if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
    
    
				return KotlinDelegate.instantiateClass(ctor, args);
			}
			else {
    
    
				构造器的构造参数类型;
				Class<?>[] parameterTypes = ctor.getParameterTypes();
				Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
				构造方法入参;
				Object[] argsWithDefaultValues = new Object[args.length];
				for (int i = 0 ; i < args.length; i++) {
    
    
					if (args[i] == null) {
    
    
						Class<?> parameterType = parameterTypes[i];
						argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
					}
					else {
    
    
						argsWithDefaultValues[i] = args[i];
					}
				}
				创建Bean对象 传入入参 假设没有 就没有入参;  到这里 Bean的实例化 彻底走完;
				return ctor.newInstance(argsWithDefaultValues);
			}
		}
		catch (InstantiationException ex) {
    
    
			throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
		}
		catch (IllegalAccessException ex) {
    
    
			throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
		}
		catch (IllegalArgumentException ex) {
    
    
			throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
		}
		catch (InvocationTargetException ex) {
    
    
			throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
		}
	}

总结

到这里 Bean的实例化 就彻底完成 也了却了同学们 念想的 Bean的创建吗; Bean创建后 就是之前讲的 Bean的初始化; 分 初始化前 初始化 初始化后; 这里我相信同学们都已经掌握了其知识要点 如果又疑问 可以私聊作者; 随后 就是Bean的销毁;

Bean的销毁

Bean的销毁 并不是特别复杂; 并且 在正式的项目中也比较少用到Bean的销毁;
Bean销毁是发送在Spring容器关闭过程中的。 ​
在Spring容器关闭时,比如:

  		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(testMain.class);
        context.close();

在Bean创建过程中,在最后(初始化之后),有一个步骤会去判断当前创建的Bean是不是DisposableBean:
1:当前Bean是否实现了DisposableBean接口 或者,当前Bean是否实现了AutoCloseable接口
2:BeanDefinition中是否指定了destroyMethod @PreDestroy
3: 调用DestructionAwareBeanPostProcessor.requiresDestruction(bean)进行判断 ApplicationListenerDetector中直接使得ApplicationListener是DisposableBean
InitDestroyAnnotationBeanPostProcessor中使得拥有@PreDestroy注解了的方法就是DisposableBean
4:把符合上述任意一个条件的Bean适配成DisposableBeanAdapter对象,并存入disposableBeans中(一个LinkedHashMap)

以上 就是Bean的创建过程中 对于销毁的动作;

在Spring容器关闭过程时:
1.首先发布ContextClosedEvent事件
2.调用lifecycleProcessor的onCloese()方法
3 销毁单例Bean
1).遍历disposableBeans
a. 把每个disposableBean从单例池中移除
b.调用disposableBean的destroy()
c.如果这个disposableBean还被其他Bean依赖了,那么也得销毁其他Bean
d.如果这个disposableBean还包含了inner beans,将这些Bean从单例池中移除掉
清空manualSingletonNames,是一个Set,存的是用户手动注册的单例Bean的beanName
清空allBeanNamesByType,是一个Map,key是bean类型,value是该类型所有的beanName数组
清空singletonBeanNamesByType,和allBeanNamesByType类似,只不过只存了单例Bean

这里涉及到一个设计模式:适配器模式
在销毁时,Spring会找出实现了DisposableBean接口的Bean。 ​

但是我们在定义一个Bean时,如果这个Bean实现了DisposableBean接口,或者实现了AutoCloseable接口,或者在BeanDefinition中指定了destroyMethodName,那么这个Bean都属于“DisposableBean”,这些Bean在容器关闭时都要调用相应的销毁方法。

所以,这里就需要进行适配,将实现了DisposableBean接口、或者AutoCloseable接口等适配成实现了DisposableBean接口,所以就用到了DisposableBeanAdapter。

会把实现了AutoCloseable接口的类封装成DisposableBeanAdapter,而DisposableBeanAdapter实现了DisposableBean接口。

大总结

对于Bean的销毁 源码 我就不带大伙进行详细的分析; 如果有兴趣的 可以自己去看; 流程已经很细致的告诉大家了; 到这里 Bean的生命周期 算讲完了; 之后 我们就会进入到Bean的依赖注入; Bean 是怎么依赖注入的呢? 大伙可以认真思考以下; 实在什么地方注入的? 是在实例化 还是在初始化; 还是? 循环注入是怎么一回事? Spring怎么解决的循环注入? @Autowired 到底是怎么一回事??

see you ;

猜你喜欢

转载自blog.csdn.net/wenaicoo/article/details/120258823