spring生命周期随笔

spring生命周期上:

要注意的是spring启动的时候已经经过了spring的生命周期了

transformBeanName(name)

getSingleton(beanName)是可以拿到

getObjectForBeanInstance 是不是factoryBean
name 程序员传入、beanName 真名

双重机制校验
普通bean直接返回
是factoryBean执行下面的逻辑

从缓存中调用
factoryObejctCanche
当前缓存没有 强制转换成factoryBean ,因为他要调用getObject方法
doGetObjectFromFactoryBean

// 调用BeanPostProcessor执行初始化后的逻辑,主要就是进行AOP

调用初始化之后的方法 因为他可能要进行aop做动态代理
得到的对象要看他是不是实现了factoryBean

所以FactoryBean相当于是懒加载 。只有在调用getBean(factoryBeanName)的时候才会调用getObject方法去获取User 对象

getObject的user对象会放到容器中:
就是factoryBeanObjectCache 容器中 而LubanFactoryBean就会放到singletonObjects 0:41:00

beanFactroy是大工厂 ,spring中所有的Bean 都是由BeanFactory创建出来的 。它可以创建普通bean 和特殊bean 、单例bean原型bean
FactoryBean是通过beanFactory 创建出来的
FactoryBean是一个小的工厂 ,只能产生一个对象。 或者scope是 原型的 ,可以产生同一个类型的多个对象

factoryBean的作用 有的时候我们希望自己构造一个对象,把他放到Ioc容器中

这边getBean("user") 拿不到User这个对象 ,因为这个User对象不是一个配置类, 不能够生成Bean定义

@component
public class UserService{
@Autowired
private UserMapper userMapper;

}
UserMapper接口 ,需要把UserMapper接口的代理对象注册到Ioc容器中。。 既可以有代理对象 又需要注册到容器中
在我们的容器中我们需要一个UserMapper的代理对象

还有啥方式: 如何把我们自己new 出来的对象 放到容器中呢??
1、@Bean 功能比较单一 ,只能写在方法上 , 这个方法内部也能够 弄一个代理对象出来
2、class 实现 FactoryBean 接口之外,还能够 实现其他接口 BeanClassLoaderAware
回调函数可以 拿到这个类是哪个 类加载器加载
00:00 - 00:58:543 都在讲一个东西就是FactoryBean

bean的生命周期
进行扫描,扫描类
生成Bean

推断构造方法 , 加载类之后要实例化对象的话,多 个构造方法要选哪一个呢 所以会去推断构造方法
属性赋值就是依赖注入

有一个问题,当我们在扫描的时候,扫描到userService这个类的时候,我们没有去加载这个类,我们说的加载这个类指的是生成这个类的class
对象放到jvm中去,我们在扫描的时候没有做到这一步。。。 那我们如何发现UserService这个类上面是否有component这个注解呢 ,第一步进行扫描,然后我们用的asm技术
解析字节码文件 识别这个类的信息 生成一个beanDefintion

入口 :

怎样实例化非懒加载的单例ban

合并之后的bd 叫做rootBd
合并之前的叫做 genericBd
bd常用的类型
bd是接口 有实现类
genericbd 是支持拥有父
rootbd 不支持parent
创建bean 一定是拿合并之后的bd 就是拿rootbd,
不会去改扫描出来的bd 就是genricBd
就只是会生成mergedBd

beanName --》mergedMap ==》genercicBeanDefintion -parent -》rootBeanDefintion

合并bean定义

抽象的不能生成bean定义 抽象类不能实例化--》

@dependSon 注解
程序员自定义的

a depends on b
b depends on a
无法创建

@component
@dependson("orderService")
public class UserService(){
}

@component
@dependson("userService)
public class OrderService(){
}

RequestScope AbstractRequestAttributesScope
SessionScope AbstractRequestAttributesScope

"RequestScope":RequestScope
"session":SessionScope
get方法
结论:

"request" ,UserService -->>Bean对象 request.getAttribute().get("beanName")
"session" ,UserService -->>Bean对象 session.getAttribute().get("beanName")

doCreateBean spring自带的创建方法
resolveBeforeInstantiation(beanName, mbdToUse); 让程序员自己返回一个bean 实现方法用bean的后置处理器

bean的后置处理器 ,spring在创建bean的过程中,我们可以设置一些bean的后置处理器去干涉soring创建bean的过程

实例化之前的bean后置处理器 得到bean 则再执行初始化后的bean后置处理器 因为它跟aop 有关系 不能够拒绝aop

填充属性 @Autowired
populateBean(beanName, mbd, instanceWrapper); //

初始化 和 BeanPostProcessor 正常AOP BeanPostProcessor
exposedObject = initializeBean(beanName, exposedObject, mbd);
initializeBean 中 1、 执行aware
2、 初始化之前 @pointConstruct
3、初始化 调用 实现了InitializingBean 接口的
4、 初始化后

对于任何一个bean 他都有一个beanName

还要判断从单例池拿到的bean是不是一个factoryBean

如果是原型的就直接去创建bean 不去单例池拿了

createBean 是如何创建Bean

第一步:
加载类
beanName mbd
如何返回class对象

AbstractBeanDefinition 的
@Nullable
private volatile Object beanClass; // String Class
获取BeanDefinition中所指定的beanClass属性的值,beanClass属性的类型为Object,可以指定为某个类名
// className可以有SpEL,所以需要解析

@Component
public class UserService(){
@value("#{orderService}") // 可以注入成功
private OrderService orderService;

public void test (){

sout(orderService;)}
}

@value("#{orderService1}") 报错

表示是表达式

@value("${orderService1}") 报错
$表示是占位符 需要填充 用什么填充呢 ,用的是spring的Enviroment

1、定义properties
2、vm options 的时候指定 -D LunbanXX=123

@Autowired 是先byType 再byName

rootbeandefintion 中 beanclass = "com.lunban.UserService"
beanClass 是一个全限定名去加载类,然后重新设置回bean的class属性
asm技术

spring用什么类加载器 去加载类呢 ?

AbstractBeanFactory  
 	@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();

Thread.CurrentThread().setContextClassLoader(XXX);
applicationContext.getBeanFactroy().setBeanClassLoder(xxx) 程序员自己指定的类加载器
会利用BeanFactory所设置的类加载器来加载类,。

AbstractBeanFactory 类 
 	@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();

如果没有上面的BeanFactory没有设置,则默认使用ClassUtils.getDefaultClassLoader()所返回的类加载器来加载

ClassUtils.getDefaultClassLoader()

  1. 优先获取当前线程中的ClassLoader(正常情况下,就是AppClassLoader)
  2. 如果为空,则获取加载ClassUtils类的类加载器(正常情况下,就是AppClassLoader,但是如果是在Tomcat中运行,那么则会是Tomcat中为每个应用所创建的WebappClassLoader,tomcat会在前面设置)
  3. 如果为空,那么则是bootstrap类加载器加载的ClassUtils类,那则获取系统类加载器进行加载 系统类加载器默认返回的是appClassLoader

luban 第三期spring生命周期下 00:53:19
什么叫做bootstrap加载 ,spring项目的jar包放到 jre/lib下 放到这个目录下面的类 都会用bootstrap 加载

类加载器的 看jvm 里面有讲。。。。。。。。。

// 如果没有设置,则默认使用ClassUtils.getDefaultClassLoader()所返回的类加载器来加载
如果BeanFactory所设置的类加载器来加载类为空,则获取加载ClassUtils类的类加载器(正常情况下,就是AppClassLoader,但是如果是在Tomcat中运行,那么则会是Tomcat中为每个应用所创建的WebappClassLoader)

asm技术解析字节码生成bd文件

Object bean = resolveBeforeInstantiation(beanName, mbdToUse); // 对象 在doCreateBean之前

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

// 4.1、执行Aware
invokeAwareMethods(beanName, bean); BeanNameAware BeanClassLoaderAware BeanFactoryAware

UserService 实现了InitializingBean,ApplicatioContextAware(对ApplicationContextAwareProcessor)

// 4.2、初始化前
ApplicatioContextAware 在 初始化前执行 对ApplicationContextAwareProcessor ---》applyBeanPostProcessorsBeforeInitialization

// 4.2、初始化前
@pointConstruct注解 ---》applyBeanPostProcessorsBeforeInitialization InitDestroyAnnotationBeanPostProcess --》 找注解 pointConstruct注解 preDestroy 注解
InitDestroyAnnotationBeanPostProcess -》CommonAnnotationBeanPostProcess 的父类

// 4.3、初始化
afterPropertiesSet 在初始化时候执行 ---》invokeInitMethods(beanName, wrappedBean, mbd);

有一个判断逻辑 为什么 不行 ,因为luBanBeanPostProcess 的postProcessBeforeInitialization 方法返回空了,而且因为luBanBeanPostProcess 优于InitDestroyAnnotationBeanPostProcess 执行,只要保证
luBanBeanPostProcess 的postProcessBeforeInitialization 方法执行不为空 就能让 CommonAnnotationBeanPostProcess(InitDestroyAnnotationBeanPostProcess) 执行 的postProcessBeforeInitialization (调用@pointConStruct方法)
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		// BPP1--》BPP2-->BPP3
		Object current = processor.postProcessBeforeInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

上一个beanPostProcess 执行完之后没有返回 下一个bpp 就不会执行

加载类
实例化前 --》 bpp InstantiationAwareBeanPostProcessor 只有他有 postProcessBeforeInstantiation
实例化
BeanDefinition的后置处理 --》 对bd进行操作 BeanDefinition的后置处理 MergedBeanDefinitionPostProcessor --》 postProcessMergedBeanDefinition
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 运行修改合并好了的BeanDefinition
// 这里会查找@Autowired的注入点(InjectedElement),并把这些注入点添加到mbd的属性externallyManagedConfigMembers中
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}

实例化后 --》 bpp InstantiationAwareBeanPostProcessor 只有他有 postProcessAfterInstantiation
填充属性
填充属性后 --》 InstantiationAwareBeanPostProcessors 中的 postProcessPropertyValues 、postProcessProperties 进行依赖注入
aware
初始化前 --》 bpp postProcessBeforeInitialization
初始化
初始化后 --》 bpp postProcessAfterInitialization

实例化前 --》 bpp InstantiationAwareBeanPostProcessor 只有他有 postProcessBeforeInstantiation 这边返回bean了就直接执行初始化后的方法
初始化后 --》 bpp postProcessAfterInitialization
// 实例化前
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}

@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	Object bean = null;
	// beforeInstantiationResolved为null或true
	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
		// Make sure bean class is actually resolved at this point.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			Class<?> targetType = determineTargetType(beanName, mbd);
			if (targetType != null) {
				// 实例化前
				bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
				if (bean != null) {
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
		}
		mbd.beforeInstantiationResolved = (bean != null);
	}
	return bean;
}



​ // 2、实例化
​ if (instanceWrapper == null) {
​ // 创建bean实例 new USerSerive()
​ instanceWrapper = createBeanInstance(beanName, mbd, args); 这里回进行推造构造方法 , 我们要选哪一个构造方法呢 后面会将
​ }

实例化前返回对象就不会填充属性
实例化后返回false 就不会填充属性

@Component
public class LubanMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    if (beanName.equals("userService")) {
        beanDefinition.setBeanClass(User.class); // 没用
		 beanDefinition.setInitMethodName("initLuBan");
        beanDefinition.getPropertyValues().add("name","xxx");
    }
}

}

@component
public class UserService{
public void initLuBan(){
sout("initLuBan");
}

}

在初始化的方法中
invokeInitMethods(beanName, wrappedBean, mbd);

西面这段代码在初始化的最后

if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd); // init-method=""
}
}
就会执行这段代码 很六六六 。。

初始化的过程可以做验证 。。。。。 spring提供了各种钩子函数 。。。。

posted @ 2021-09-14 07:14  笨拙的小菜鸟  阅读(100)  评论(0编辑  收藏  举报