spring注解原理

ioc有2步:1.通过无参构造创建对象,2.通过set方法,构造方法,字段,依赖注入(有2种:1.手动注入,2.自动装配 byName or byType)

=================================

spring Ioc 的核心 就是获取 到 类的 class对象

================================

ioc容器创建对象的3种方式

	1.获得beanDefinition,通过无参构造创建对象后,然后通过set方法赋值
		1.@auwire filed属性
		2.@auwire set方法
	2.获得beanDefinition,通过有参构造创建对象
		1.@auwire 有参构造器

	3.上面两种方法的相同点,都会用到 @auwire注解
		1.@auwire 属性
			会从 ioc容器中 找到 @auwire 修饰的 属性的 实例,赋值
			
		2.@auwire 方法
			根据修饰的参数列表,去容器中 找到 对应的实例,赋值,并且执行 @auwire修饰的方法
			
	4.区别:当@auwire修饰 有参构造的话,就直接有参构造出实例

	5.这样@auwire使用的场景,就可以根据你的需要
		1.只是对 属性赋值,没有任何其他想要做的,@auwire 属性
		2.不仅想对属性赋值,而且想要用 @auwire 修饰方法,不仅会对 参数列表赋值,而且执行这个方法这个特性
		  去完成对属性的赋值,以及 做一些 其他事情(在 我们访问 controller之前)
		  包括,去 创建一些对象等等
	
	3.获得 调用 @bean方法创建对象

=================================

单实例对象 是 缓存在ioc容器中的,所以可以用来解决 循环依赖问题,而多实例对象是 不缓存在ioc容器中的,所以不能解决循环依赖问题,因为多例根本不能属性注入

===============================

beanFactory.getBean(),首先都会去看缓存中是否有,有直接返回,没有再看自己有没有其beanDefinition,有那么beanFactory自己创建后加入自己的缓存,如果没有,那么就得从外部手动创建单实例bean,然后用beanFactory加入自己的ioc容器缓存中

=================================

Spring容器会将每一个正在创建的Bean 标识符放在一个“当前创建Bean池”中,Bean标识符在创建过程中将一直保持此时若bean在创建的过程中,依赖的一个bean,发现这个bean在“池中”将抛出BeanCurrentlyInCreationException异常表示循环依赖;而对于创建完毕的Bean将从“当前创建Bean池”中清除掉。

=================================

full和lite配置类的区别:就是@bean交不交给代理对象执行的问题:lite配置类(),如果你执行@bean方法,就是简单的执行@bean方法,执行多次,就会生成多个bean,就不能保证单实例,那么ioc容器是不会缓存 多实例对象的

Configuration(full-完整配置类)

	1.除了可以有 @compoent注解的作用,也还可以自己调用 @Bean方法生成对象的作用
	
	2.标注了@configuration的FULL配置类,在FULL配置类中注册的 组件类,会在
		  ConfugurationClassPostProcessor#postProcessBeanFactory()方法中被
		  ConfiguratioClassEnhancer 代理,交由容器 处理依赖关系
		  意思就是@configuration相比其他配置类的区别,就是动态代理,@Bean方法生成对象,会交给代理类执行
		  这样就保证了,@Bean方法只会返回一个单例对象
		  
	3.唯一区别:就是@Configuration 有 proxy代理对象,对象的依赖交给容器管

	4.生成的配置类是 代理对象,而不是@bean的 是 代理对象

	5.full配置类和lite配置类,和 @bean 的单实例 还是 多实例 没半毛钱关系
	spring启动,去 ioc bean ,但是 你直接 调用 @bean方法,如果 配置类是
	full配置类,就会调用代理对象的方法,getBean 首先直接从缓存中取,如果缓存中没有(即 @bean是 多实例的)
	那么,就会创建 一份然后返回,也不存缓存
	简单来说就是 调用 @bean方法,代理对象执行 这个方法,里面具体就是 beanFactory.getBean()
    是单实例,缓存中有返回,是多实例,缓存中没有,创建返回,不存缓存
    也就是说,full还是lite 和 代理对象有关,跟 @bean的 scope无关,如果是lite
    那么 就是直接 执行 @bean方法了(跟 ioc容器没有任何关系)
    如果是full , 就会调用代理对象的 @bean方法,里面具体是 BeanFactory.getBean()
    这就跟 ioc 容器有关系了,

@bean,@Scope,@Lazy

	1.默认@bean,只在spring启动的时候调用一次,生成单例对象
		  如果@Bean在 @Configuration配置类里面 proxyBeanMethods() default true;默认使用的是代理对象生成 单例对象的
			  例如,一个Bean里调用了另一个bean方法,那么是不是意味 这另一个bean方法要调用2次?
			  不是,第二次调用会用 proxy代理对象,这样返回的bean还是之前第一次的bean
		  如果@Bean 在 lite配置类中,那么就没有 proxy,就是简单的 调用 @bean的方法
	  
	2.@Scope修饰在@Bean上,可以改变其加载模式,例如多实例的,那么就是
	  在从 ioc getBean() 的时候调用 @Bean修饰的方法,每从Ioc中get一次调用一次
	  这个 proxyBeanMethods 就是 false了,就不会用代理对象去调用 bean方法,就会直接调用 配置类里面的 bean方法
	  
	3.@Lazy,解决单实例的懒加载问题,设置后,可以在第一次 getBean的时候调
	  用,生成单例对象,下一次从 ioc 中拿的时候就不在调用了直接拿 第一个

条件装配(和@configuration @bean一起使用)@conditional({condition数组}) ,大量使用在boot底层,当然还有@conditionalON…,on表示有没…,那么加载或者不加载

	1.可以修饰在 类上 或者 方法上,重写 condition,里面的方法,
	
	2.若修饰在方法上 首先 configuration类肯定会被创建,return true那么 加载bean,return false那么不加载bean
	
	3.修饰在 @configuration类上,return true那么 configuration类 并且 里面的 所有@bean方法 加载
	反之,configuration类,以及其@bean生成对象 都不会加载

componentScan(扫描指定包下的,controller…注解,子注解是这几个就行,底层扫描是递归算法,至于如何扫描到的,并且得到他们的 class对象的,不做了解)

	1.@ Filter可以规定扫描规则

只有import产生的 definition的id 是全类名的,其他的都是类名小写,或者方法名

@import({普通类.class})id为全类名

	1.通常用于 第三方组件的 注入,和普通的spring 通过 class对象创建对象没有区别
	
	2.@bean也是用于第三方组件的注入,但是@bean是调用构造方法,spring创建其对象
	  也是调用@bean方法,只是它里面我们只有 new 对象 才能创建对象  

@import ({importSelector接口实现类.class})ImportSelector 的实现类可以基于对应配置类的 AnnotationMetadata 属性进行 select,同时还可以实现各种 Aware 接口类似 EnvironmentAware BeanFactoryAware 等,持有对应的 Environment BeanFactory 来进行 select,但是importSelector接口实现类不会被ioc

	public interface ImportSelector {

	// 返回 全类名 字符串,创建对象
	//AnnotationMetadata:当前标注@Import注解的类的 所有注解信息 包括import
	String[] selectImports(AnnotationMetadata importingClassMetadata);
	
	
	// 允许提供一个 Predicate 过滤 selectImports 方法对应的类
	@Nullable
	default Predicate<String> getExclusionFilter() {
		return null;
	}
}

@import ({importBeanDefinitionRegistrar接口实现类.class})主要是,用里面的BeanDefinitionRegistry registry,这个注册beanDefinition的注册库来注册组件,自己可以创建一个 beanDefinition,然后调用 registry.registerBeanDefinition(“BeanDefinition名”,beanDefinition)

	public interface ImportBeanDefinitionRegistrar {

		// 基于 AnnotationMetadata BeanDefinitionRegistry 注册对应的 BeanDefinition
		default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
				BeanNameGenerator importBeanNameGenerator) {
	
			registerBeanDefinitions(importingClassMetadata, registry);
		}
	
		default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		}
	
	}

注册 FactoryBean,工厂bean

	1.FactoryBean是一个接口,他有几个方法
		1.getObject  beanFactory.getBean 创建对象的是够,发现是工厂bean,那么会调用这个 getObject() 方法 创建工厂bean对象,
		
		  然后把它加入 beanFactory,beanFactory下次在获取的时候,直接从缓存中得到这个对象
		  
		2.isSingle 默认 return true,若为 false,那么每次getBean,就会调用一次 getObject,下一次也不会从缓存中拿
		
	2.spring底层用了很多
	
	3.注册 MapperFactoryBean就是用了这个 工厂bean返回的 mapper代理对象
	  并且 返回的 是 单例的

	4.简单来说,只要是工厂bean,在创建/get bean的时候,beanFactory.getBean()
	首先,看缓存中有没有,有那么直接返回,没有,判断工厂类,直接执行它的getObject方法
	生成对象,若是 单例存缓存(缓存中存的对象类型是,getObject方法里面生成对象的类型
	不是,工厂bean的类型)
	若是多实例的,那么不会存缓存,直接返回

	并且在 依赖注入的时候,id为 工厂bean的 缓存中的对象,类型可不跟 工厂bean的类型一样

Bean的生命周期(简易版)

	1.单例对象,spring会自动销毁,会调用销毁方法
	
	2.多例对象,spring不会自动销毁,也不会调用销毁方法,需手动销毁
	
	3.生命周期包括 bean创建,属性赋值,前置,初始化,后置,bean获得,销毁 7步,每一步方法 return 都是 bean对象
	
	4.bean初始化,和销毁方法的 指定方法
		1.在 bean对象中,编写 init和destroy方法,然后在@Bean注解中的init-method和destroy-method属性指定
		
		2.bean 对象实现 initializingBean和disposableBean接口的 destroy和afterPropertiesSet初始化方法,来执行初始化和销毁方法
		
		3.使用 jsr250规范的两个注解
			1.@PostConstruct
			2.@PreDestroy
			将这两个注解加在 自定义bean的 自定义初始化和销毁方法上即可
			
	5.BeanPostProcessor 初始化 前后置方法
		1.实现 BeanPsotProcessor接口的 PostProcessorBeforeInitization(Object bean,String beanName)方法和
		  PostProcessorAfterInitization(Object bean,String beanName)方法
		  对bean 在 初始化 前后 做一些处理后 返回 bean
		  
	6.BeanPostProcessor工作原理(什么叫遍历all BeanPostProcessor,就是说除了你自己定义的 BeanPostProcessor,
								还包括,spring原生的 BeanPostProcessor)
		1.创建对象
		
		2.populateBean(beanName,mbd,instanceWrapper);给bean注入依赖
		
		3.initializeBean(简易 四步)
			1.invokeAwareMethods();处理Aware接口的 方法回调这一步
			
			2. applyBeanPostProcessorBeforeInitialization(wrapperedBean,beanName)
			   遍历得到容器中所有的BeanPsotProcessor,挨个执行PostProcessorBeforeInitization
			   当 return null,跳出for循环,不再执行后面的
			   
			3.invokeInitMethods(beanName,wrappered,mbd);初始化
			
			4.applyBeanPostProcessorAfterInitialization(wrapperedBean,beanName)
			   遍历得到容器中所有的BeanPostProcessor,挨个执行PostProcessorAfterInitization
			   当 return null,跳出for循环,不再执行后面的
			   
			5.最后经过一系列处理的 bean就是 最终的 bean

# 后置处理器分很多种,并且每种在bean创建的时机,和作用都不一样(举两个例子)

	1.implents BeanPostProcessor接口的
		它的前后置方法叫做 postProcessBeforeInitization()
		它的作用就是常规的 后置处理器的作用(在bean 创建完成初始化前后调用)
		
	2.implents InstantiationAwareBeanPostProcessor extends BeanPostProcessor接口的
		它的前后置方法叫做 postProcessBeforeInstantiation()
		它的作用 是在 bean创建之前,尝试用 后置处理器 返回 代理对象bean的

Spring底层 常规的(implents BeanPostProcessor)BeanPostProcessor底层原理(其目的就是来完成 bean获取前 对bean的处理的)

	1.spring里面有大量的 BeanPostProcessor的实现类
	
	2.包括自己自定义的 BeanPostProcessor实现类
	
	3.在对象创建出来后,所有的bean都得 经过 所有的 beanPostProcessor实现类的
	  PostProcessorBeforeInitization方法 走一遍,最后返回的bean才是最终的bean
	  
	4.那么spring底层 有哪些 BeanPostProcessor,他们的前置和后置都有哪些作用呢
		1.AsyAnnocationBeanPostProcessor 处理异步方法的,处理 异步注解的
		
		2.AppicationContextAwareProcessor 
			所有的bean,经过这个processor的时候,这个processor会检查这个bean是否实现 ApplicationContextAware接口
			如果是,那么会调用它的 setApplicationContext(ApplicationContext ac)方法
			将 ioc容器 传给它,便可以获得 ioc容器
			
		3.InitDestroyAnnotationBeanPostProcessor
			 找到bean的 @postConstruct,@preDestroy修饰的方法,
			 如果有,那么就会 在初始化bean 调用前后,调用这两个方法
			 
		4.AutowiredAnnotationBeanPostProcessor
			找到bean的 @autowired修饰的地方,并且调用 自动装配的 方法
			
	5.总之:beanPsotProcessor,是来处理 bean的,其作用点有:bean赋值,注入其他组件
			@autowired,生命周期注解,@Async........作用,这是 spring的一种思想,来解决 bean创建的过程中 来处理一些事

自定义组件 想要使用 spring容器底层的一些组件(spring提供了,aware接口,和发现 aware接口实现类的 BeanPostProcessor)例如

	1.我们想用ApplicationContext组件,所以Spring提供 ApplicationContextAware接口,以及发现它的 ApplicationContextAwareProcessor BeanPostProcessor
	  我们实现这个 aware接口 重写里面的 serApplicationContext(ApplicationContext ac)方法,
	  那么spring 的 awareBwanPostProcessor会找到这个 实现类,然后调用其setApplicationContext(ApplicationContext ac )方法
	  将 ac 传给这个方法,我们用 实例变量保存取来即可
	  
	2.这是spring的一种设计思想,即通过 beanPostProcessor,在创建bean的过程中做一些操作,
	  这种 找到 aware接口实现类 并调用 其方法,传给我们 底层组件的方式,也是这种思想

@profile注解 运行环境注解(profile只是 指定 在某个环境下 那些bean可以ioc,跟 具体的环境设置没有关系)

而且你用 @profile的时候,一个类或者方法用了 @profile,必须有相同的类和方法 用profile , 因为 如果只有一个 profile,那么一旦这个环境没有了,而你其他位置 依赖注入了这个bean,就会报错,所以准备相同 id的多个 bean实例,对他们加上 @profile 那么 在 一个环境下,一定有一个bean可以 ioc,那么 用到他们的地方,就能注入依赖了,也就不会报错,也体现了@profile的 不同环境生成不同 bean的的作用,我们的业务也能根据 环境不同 拿到相同id 的 不同的 一个bean

而 我们 可能因为 语法的原因,不能 创建相同id的 bean,但是也是有办法的,例如不同id的bean 实现相同的接口,这样他们都能ioc , 然后注入依赖的 地方,用 接口注入依赖,这样就可以了
1.@profile注解可以作用 在 类上和 @Bean 方法上,作用在@Bean上,只有在这个环境被激活的时候,@bean才生效
作用在类上,只有在这个环境被激活的时候,整个类的注解才生效

	2.profile的默认 是 “default”环境
	
	3.不指定 profile注解的,在任何环境下都可以注册这个组件,这些注解都生效
	
	4.修改 spring运行环境的 2种方式
		1.使用 命令行 动态参数:在VM 参数位置,加载 —Dspring.profiles.active = 环境标识(可以是多个)
		
		2.1.在创建 ioc容器的 时候 使用无参构造 ac = new ApplicationContext()
		
		  2.设置需要激活的 环境applicationContext.getEnvironment().setActiveProfiles("") 环境可以设置多个
		  
		  3.注册主配置类 ac.register()
		  
		  4.刷新日期 ac.refresh()

springboot运行环境的几种设置方式

	1 在 cmd 命令中指定
	  java -jar xxx.jar --spring.profiles.actvie=dev 

	2.在 application.yml 中指定
	  spring:
	   profiles:
		  active: dev
	  (注意,这是试用多个 配置文件的,配置中心的也是一样,你就看 有几个配置文件(配置中心的配置文件也算上)
	  然后,主配置文件的 active是什么,那么主配置文件,和其 名中有 active的配置文件
	  都会被加载,然后此时的 运行环境就是 active)

	3.在IDEA 编辑器中指定
	  在运行按钮(绿色三角形按钮)旁边选择 Edit Configurations...,在弹出的对话框中 Active profiles 输入 dev 或其他即可。
	  这种方法只有在本地调试的时候才生效。

aop(底层动态代理,spring+aspectj2个框架完成的aop操作,spring底层就是解析这些注解,然后调用动态代理来完成的)

	1.aop应用层的几个注意点
		1.逻辑类(要注入到 ioc容器中)
		
		2.aspectJ代理类(要注入到 ioc 容器中)
		
		3.代理类里面的 通知注解(切入点表达式)
		
		4.几大通知的执行时机:
			1.@AfterReturning 后置通知(返回值通知)只有逻辑类正常返回才会执行
			
			2.@After 最终通知 无论如何都会执行,如果不能正常返回那么会执行 异常通知,最后After 最终通知 还是会执行
			
			3.@AfterThrowing 异常通知,逻辑类出现异常,会执行这个通知
			
			4.@Around 通知,这个是 手动 来 执行 逻辑类代码的
				 System.out.println("环绕之前.........");
				 //被增强的方法执行
				 proceedingJoinPoint.proceed();
				 System.out.println("环绕之后.........");
				 
			5.@Before 前置通知
			
		4.@Pointcut(value = 切入点表达式) 相同切入点抽取
			这个注解作用在 方法上,以后其他通知引入这个相同的 切入点表达式
			@通知(value = @Pointcut修饰的 方法名)即可引入这个 相同的切入点表达式

		5.EnableAspectJAutoProxy 开启 基于注解 的 aop模式
		
		6.如何在 代理类中 获取 逻辑类的 方法名,参数,返回值,以及异常消息
			1.JoinPoint 这个类就包含了 逻辑类的 方法,参数消息
			
			2.返回值:在@AfterReturning(return = "result")通知修饰的 返回通知里面
			          return属性 的 值,在 方法里面 可以用 方法(Object result)来接收
			          只能在 这个通知里面 获取 返回值,因为只有有返回值,这个方法才会执行
			          
			3.异常:在@AfterThrowing(throwing = "exception")通知修饰的 异常通知里面的
			        throwing属性 的值,在方法里面 可以用 方法(Exception exception)来接收
			       只能在这个 通知里面 才能 获取 Exception,因为只有有异常,这个方法才会执行
			       
			4.JoinPoint 和 返回值 和 Exception ,在通知 方法参数列表中,JoinPoint一定要写在最前面,spring和AspectJ才能识别

aop底层原理之 EnableAspectJAutoProxy

	1.进入EnableAspectJAutoProxy是
	
	2.@Import({AspectJAutoProxyRegistrar.class}),这是一个register.class,会调用 它的 registerBeanDefinitions(beanRegistry),
	  用beanRegistry来注册 beanDefinition,
	  最后就是注册 一个 AnnotationAwareAspectJAutoProxyCreator这样一个 beanDefinition
	  
	3.AnnotationAwareAspectJAutoProxyCreator的继承树
		->AspectJAwareAdvisionAutoProxyCreator
			->AbstractAdvisionAutoProxyCreator
				->AbstractAutoProxyCreator
					->implents SmartInstancetiationAwareBeanPostProcessor
					  implents BeanFactoryAware
					  
	4.总结 AnnotationAwareAspectJAutoProxyCreator是一个 后置处理器,也是一个Aware
	  这个后置处理器是实现InstantiationAwareBeanPostProcessor 接口的,作用是:在bean创建之前,尝试用后置处理器返回代理对象的
	  aware接口可以被 对应的后置处理器拦截,并执行回调方法,获得BeanFactory ioc 容器

AnnotationAwareAspectJAutoProxyCreator为角度的 bean的创建过程(简易版)

	1.传入配置类,创建ioc容器 beanFactory 此时bean还没有创建,只是有bean的定义信息
	
	2.注册配置类,调用refresh()刷新ioc容器(创建bean,包括实现所有功能)
	
	3.refresh()详解
		1.创建beanFactory(包含所有各种类型的bean,包括后置处理器,监听器的beanDefinition,才时候bean没创建)
		
		2.postProcessorBeanFactory(beanFactory) 注册beanFactoryPostProcessor包括其子接口
		
		3.invokeBeanFactoryPostProcessors 执行这些beanFactoryPostProcessor包括其子接口
		
		4.registerBeanPostProcessors(beanFactory) 注册后置处理器
		  (先将所有的 后置处理器创建并注册到 BeanPostProcessorsList中
		  然后再创建普通bean,这样这些 常规的 beanPostProcessor就可以用于拦截bean的创建,并包装bean)
		  	1.拿到beanRegistry 中的 所有 后置处理器 beanDefinition
		  	
			2.容器 还会 加入 其他 BeanPostProcessor 的 beanDefinition
			
			3.然后创建 BeanPostProcessor对象
				1.优先注册 实现了 priorityOrdered 接口的 BeanPostProcessor
				
				2.再 注册 实现类 Ordered 接口的 BeanPostProcessor
				
				3.最后 在注册 啥都没实现的 BeanPostProcessor
				(创建完 一个 beanPostProcessor,就会 add 入 list集合,并且给list中的 beanPostProcessor排序)
				
					对3.3创建 beanPostProcessor的过程详细解释
						1.创建 beanPostProcessor,实际上就是 调用 beanFactory.getBean(beanName)
						  如果ioc 容器里面有就返回,如果没有就创建单实例
						  
						2.创建 internalAutoProxyCreator(AnnotationAwareAspectJAutoProxyCreator) 的 BeanPostProcessor
							1.创建 beanPostProcessor 的 bean实例
							
							2.populateBean bean赋值
							
							3.initializeBean 初始化bean(简易4步)
								1.invokeAwareMethods();处理Aware接口的 方法回调这一步
										1.判断 beanPostProcessor是不是 aware接口实现类,anno..Creator是beanFactoryAware接口实现类
										
										2.调用 setBeanFactory回调函数,将ioc 容器 传给 anno..Creator
										(由于 setBeanFactory是重写了的,所以每一个 aware接口实现类的 set函数的实现都不一样,这里我们探讨 anno...Creator的)
											1.super.setBeanFactory ->调用父类的 set函数(this.beanFactory = beanFactory)
											
											2.initBeanFactory(beanFactory)(这是 它 独有的)
												(这一步 利用 beanFactory 作为参数 创建了 2个东西)
												1.aspectJAdvisorFactory = new RefleticeAspectJAdvisorFactory(beanFactory)
												2.aspectJAdvisorBuilder = new BeanFactoryAspectJAdvisorBuilderAdapter(beanFactory,aspectJAdvisorFactory)
												(其实就是将 beanFactory包装了一下)
												
							    2.applyBeanPostProcessorBefore....(拿到 all 后置处理器,执行前置方法)
							    
								3.invokeInitMethods 执行初始化方法
								
								4.applyBeanPostProcessorAfter....(拿到 all 后置处理器,执行后置方法)
														
							4.BeanPostProcessor(以 Annotation..Creator为例)创建成功,并且里面有 beanFactory,以及 拿beanFactory 包装后-> aspectJAdvisorBuilder
							
							5.将 beanPostProcessor add入 list集合,并排序,这就是一个BeanPostProcessor的创建并注册到list的过程
							
							6.从上面的步骤看,创建后置处理和创建普通bean 唯一的区别,就是在初始化bean的时候多执行了一步1.invokeAwareMethods()
							  后置处理器的创建,也需要经过 所有 后置处理器的 拦截处理
							  
							7.AnnotationAwareAspectJAutoProxyCreator,这个 后置处理器 实现的 是 InstantiationAwareBeanPostProcessor extends BeanPostProcessor
							  它的 前后置方法 是 postProcessBeforeInstantiation,而一般的叫postBeforeInitization
							  它的作用是:在bean 创建之前 尝试用它来 返回 代理对象
							  
		5.initApplicationEventMulticaster() 注册事件多播器(事件派发器)
			它可以理解为,监听器的 事件源,用来派发事件给 监听器的
			
		6.registerListeners() 注册监听器
					
		7.finishBeanFactoryInitialization(beanFactory) 完成BeanFactory初始化工作:创建剩下的单实例bean
			1.beanFactory.preInstanceTiateSingletons(); 创建剩下的 单实例 bean
				1.遍历获取容器中所有的 BeanDefinition,依次通过getBean(beanName),创建对象
				
				2.getBean()->doGetBean()->getSingleton()->
				
				3.getSingelTon()
					1.先从 缓存中 获取 当前的 bean是否 被创建了,证明 bean是之前被创建过的,直接使用,否则再创建
					  只要创建好的bean都会被 缓存起来
					  
					2.缓存中没有 -> createBean(beanName,RootBeanDefinition mdb); 创建bean
						1.Object bean = resolveBeforeInstantiation(beanName,mdbToUse)
						(希望 InstantiationAwareBeanPostProcessor 后置处理器,在此能尝试返回一个代理对象
						如果能返回就返回,若不能,就继续调用 doCreateBean() 这个是真正创建一个bean实例的地方 )
							resolveBeforeInstantiation(beanName,mdbToUse)
								1.bean = applyBeanPostProcessorsBeforeInstantiation(),遍历所有的后置处理器
								  如果是InstantiationAwareBeanPostProcessor,就执行它的postProcessBeforeInstantiation() 返回 真正的 bean
								  
								2.if bean != null 
									再执行 applyBeanPostProcessorsAfterInstantiation(),遍历所有的后置处理器
								    如果是InstantiationAwareBeanPostProcessor,就执行它的postProcessAfterInstantiation(bean) 返回 bean的 代理对象
								    
				           resolveBeforeInstantiation(beanName,mdbToUse)详解
				           (这里我们只关注,需要被增强的bean的创建过程)
				           		1.postProcessBeforeInstantiation(beanName) 返回 真正的bean对象
				           			1.Object cacheKey = getCacheKey(beanClass,beanName)  拿到 bean的名
				           			
				           			2.if(this.advisedBeans.containsKey(cacheKey))
				           			  判断 当前bean 是否在 advisedBeans中(保存了 所有需要增强的 bean)
				           			  显然第一次来处理,当前bean是不在里面的 return false
				           			  
				           			3.if(isInfrastructureClass(beanClass) || shouldSkip(beanClass,beanName))
				           				1.isInfrastructureClass(beanClass) 判断当前bean是否是基础类型的(实现了 Advice,pointCut,Advisor...接口的),或者说是否是 切面(有无 @Aspect注解)
				           				    显然 需要被增强的 bean 不是 切面的 return false
				           				    
				           				2.shouldSkip() 永远 return false
				           					1.获取 候选的 增强器(切面里面的 通知方法)List<Advisor> candidateAdvisors
				           					  这些 advisor在 解析beanDefinition的时候,发现@通知注解,就已经封装成 Advisor了,这里只是 获得它们
				           					  
				           					2.每一个封装的通知方法的增强器 是 InstantiationModelAwarePointCutAdvisor类型的
				           					
				           					3.判断 每一个增强器是否是 AspectJpointCutAdvisor类型的,显然不是 使用return false
				           					
				           			4.到 @bean修饰的 方法 创建 真正的 bean对象
				           			
				           		2.postProcessAfterInstantiation(真正bean对象) 返回 bean的代理对象	
				           			1.拿到 bean的 cacheKey
				           			
				           			2.return WrapIfNecessary(bean,beanName,cacheKey) 返回 包装bean后的代理对象 如果需要的情况下
				           				1.判断 bean是否在 advisedBeans中
				           				
				           				2.判断 bean是否 切面,是否需要跳过
				           					
				           				3.//create proxy if we have advice (创建代理对象)
				           					1.Object[] specificInterceptors = getAdivcesAndAdvisorsForBean(bean.class) 获取 当前bean 所有 增强器			
				           						1.找到 all 候选增强器
				           						
				           						2.从中 获取 能用在 当前 bean的 增强器
				           						
				           						3.给增强器 排序
				           						
				           						4.最后 return List<Advisor>
				           						
				           					2.保存 当前 bean 在 advisedBeans中,表明当前bean已增强
				           					
				           					3.如果当前bean需要增强,createProxy 创建代理对象
				           						1.获取 所有 增强器 List<Advisor>
				           						
				           						2.保存到 proxyFactory代理工厂
				           						
				           						3.创建代理对象:Spring自动决定
				           							1.JDK 代理
				           							2.cglib 代理
				           							(也可以自己配置)
				           							
				           						4.给容器中 返回 当前组件的proxy
				           						
				           						5.以后容器中获取的bean就是proxy了,执行目标方法的时候,就会执行对应的invoke方法,当然可以在这个 invoke方法里面 做一个 if
				           						  (method)判断,这样一个InvocationHandler就可以应对,proxy的所有代理方法
				           						  
						2.如果 后置处理器 不能返回代理对象,那么执行 doCreateBean()创建对象
							流程就是 创建bean,populate赋值,初始化三步走流程
							
						3.遍历 所有 创建完的 单实例 bean,判断是否是SmartInitializingSingleton类型的,是就调用alterSingletonsInstantiatied(beans)
				  		  将所有 bean遍历 解析一遍@EventListener,生成对应的监听器
				  
						4.最后 finishBeanfactoryInitialization方法结束,bean也就创建完成了

Aop proxy目标方法的执行

	1. cglibAopProxy.intercept(proxy,mentod,args) 类似jdk代理的 invoke方法
		1.根据proxyFactory对象 来获取 目标方法的拦截器链 list<Interceptor>
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice()
				1.List<Object> interceptorList 用来保存所有的拦截器
				
				2.遍历所有的 Advisor ,将其 转换 成 MethodInterceptor,并且用 interceptorList add上
					1.如果是 MethodInterceptor,直接add
					2.如果是Advisor,用 AdvisorAdapter 将 Advisor 转为 MethodInterceptor,然后add
					
		2.如果没有拦截器链,直接执行目标方法		
		
		3.如果有拦截器链 Object retual = new cglibMethodInvocation(chains,proxy,method)
			1.如果没有拦截器,或者拦截器 index和 拦截器链size - 1 相等(也就是执行到最后一个拦截器),执行proxy的目标方法
			
			2.说白了,拦截器链 是 责任链模式的(类似filter的那种 栈中栈模式,一个拦截器执行过程中先调用下一个拦截器的拦截方法,然后执行自己的目标方法)
			  因为拦截器本身是有顺序的,所以必定是到了,前置拦截器的拦截方法里面,就是最后一个拦截器了,就会执行自己的方法,然后执行目标方法
		    (因为此时,拦截器 index = size -1),然后栈结束,返回到上一个拦截器,执行它的目标方法.....

Spring 事务的底层源码

	1.spring想使用事务的功能,需要这三步
		1.注册事务管理器来管理事务 spring需要注入 platformTransactionManager
		
		2.开启事务管理功能 @EnableTransactionManagement
		
		3.给事务方法,添加上 @Translation
		
	2. @EnableTransactionManagerment
		1.import(TransactionManagermentConfigurationSelector)
		  	TransactionManagermentConfigurationSelector 导入两个组件
		  		1.AutoProxyRegistrar
		  			用来注册 InfrastructureAdvisorAutoProxyCreator(是一个InstantiationAwareBeanPostProcessor后置处理器)
		  			(在bean创建前,尝试返回代理对象,并且,获取 代理对象的 所有增强器List,这个由 proxyTransactionManagementConfiguration来提供)
	
		  		2.proxyTransactionManagementConfiguration
		  			1.给容器中注册事务Advisor,想要注册这些 事务Advisor(为什么aop不用注册,因为aop可以直接解析 切面bean的通知方法,就可以得到Advisor
		  			而在事务管理中,没有切面bean,所有得自己注册 Advisor)
		  			事务增强需要用事务注解的信息
		  				1.AnnotationTranslationAttributeSource 解析事务注解
		  				
		  				2.Advisor封装成 事务拦截器
		  					TranslationIntercept:保存了事务属性信息,他是一个MethodInterceptor
		  					
		  2.事务目标方法执行的流程
		  	1.拦截器链 栈中栈 执行
		  		1.先 get 事务的相关属性
		  		
		  		2.再 获取 platformTransactionMannage,如果实现没有添加 任何事务管理器
		  		  最终会 从容器中 按照类型获取 一个platformTransactionMannager
		  		  
		  		3.执行 目标方法
		  			1.若正常:利用事务管理器提交事务
		  			2.若异常:获取事务管理器,利用它执行回滚操作

beanFactoryPostProcessor

	1.在 beanFactory创建之后,就注册beanFactoryPostProcessorList
	
	2.注册后,就立即执行,遍历所有 beanFactoryPostProcessor后置处理器
	处理,beanFactory,可以	封装 beanFactory		

beanDefinitionRegistryPostProcessor是beanFactoryPostProcessor 的子接口

	1.也是在 refresh()中的 postProcessBeanFactory()方法中完成注册
	
	2.也是在 invokeBeanFactoryPostProcessors(beanFactory)中执行
	
	3.只是,他是在beanFactoryPostProcessor 之前执行
	
	4.他可以 获得 beanDefinitionRegistry,并且用它 注册一些 beanDefinition

spring的事件监听机制

	1.spring的监听器是 ApplicationListener接口
	
	2.spring的事件对象 是 ApplicationEvent以及其子类
	
	3.spring的 事件源 是 事件多播器 applicationEventMulticaster
	
	4.spring的事件发布 是spring自动发布,或者开发者自己发布,底层都是调用publishEvent(applcationEvent event)
	
	5.【事件多播器详解】
		1.initApplicationEventMulticaster(); 初始化 ApplicationEventMulticaster
			1.先去容器中找 有没有 id = "applicationEventMulticaster"的组件
			2.如果没有 this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory)
			  并加入到容器中,我们就可以在其他组件要派发事件,自动注入这个 applicationEventMulticaster
			  
	6.【事件监听器详解】容器中的监听器注册到ioc容器,并且交给事件多播器(事件源)管理
		1.registerListeners()从容器中拿到all Listeners,并把它们注册到 ApplicationEventMulticaster中
		
	7.【事件发布流程】 publishEvent(ApplicationEvent event)
		1.获取事件的多播器
		
		2.multicastEvent派发事件
		
		3.获取 事件多播器中的 所有 applicationListeners,遍历它,将event给它执行,给的方式有2种
			1.若有 Executor(异步执行器),可支持异步执行监听器
			2.没有,那么同步执行
			
	8.spring注册监听器 的另外一种方式(可以让普通组件的 任意方法实现监听方法)
		1.在 bean的 方法上加上 @EventListener(classes = {ApplicationEvnet.class,....事件类型})
		
		2.底层是 EventListenerMethodProcessor 
					implents SmartInitializingSingleton接口
			  处理器的 void alterSingletonsInstantiatied() ,来解析@EventListener,
		  并且为之创建对应的 监听器,后面这个监听器变可以监听对应事件
		  
		3.那么 EventListenerMethodPocessor是何时工作,并解析这些 bean的方法的
		
		4.EventListenerMethodPocessor的底层原理
			1.在 finishBeanfactoryInitialization(beanFactory) 方法里面
				1.创建所有的 单实例bean 实例(包括代理bean)
				
				2.遍历 所有 创建完的 单实例 bean,判断是否是SmartInitializingSingleton类型的,是 就调用alterSingletonsInstantiatied(beans)
				  将所有 bean遍历 解析一遍@EventListener,生成对应的监听器,并将所有的监听器 添加到 事件派发器中
				  
				3.最后 finishBeanfactoryInitialization方法结束,bean也就创建完成了

spring容器创建refresh()的过程(最终版)

1.prePareRefresh() 刷新创建前的处理
	1.initpropertySource() 初始化一些属性设置;子类自定义各项的属性设置方法
	
	2.getEnvironment().validateRequiredRequiredProerties() 校验属性的合法性
	
	3.earlyApplicationEvent = new LinkedHashSet<ApplicationEvent> 保存容器中的一些早期的事件
	
2.obtainFreshBeanFactory() 获取BeanFactory(里面已经保存了 beanDefinition,也会创建 一些 bean)
	1.refreshBeanFactory() 刷新已创建的beanFactory
		1.创建一个 beanFactory
		2.设置 它的 序列化 id
		
	2.getBeanFactory() 返回刚才GenericApplicationContextc创建的 beanFactory
	
	3.return beanFactory
=====================================================
		上面 beanFactory已经创建成功
		



3.prepareBeanFactory(beanFactory) beanFactory的预准备工作(对beanFactory做一些处理,beanFactory创建一些对象)
	1.设置 beanFactory的类加载器,支持表达式解析器......
	
	2.添加部分 beanFactoryProcessor
	
	3.设置忽略 的 自动装配接口 EnvironmentAware,......
	
	4.注册可以解析的自动装配,我们能直接在任何组件中注入的组件(这时已经创建了一些bean了)
		例如:beanFactory,REsourceLoader,ApplicationEvnetPubisher,ApplcationContext.....
		
	5.添加 BeanPostProcessor【ApplicationListenerDetector 已经创建这个 beanPostProcessor】
	
	6.添加编译时的AspectJ (增强器在这一步创建)
	
	7.给 BeanFactory中注册一些能用的组件:例如 environment...
	
4.postProcessBeanFactory(beanFactory)  【注册beanFactoryPostProcessor】
	创建 beanFactoryPostProcessor及其子接口(beanDefinitionRegistryPostProcessor) 对象
	
=======================================================================
	上面 beanFactory已经创建,并且预准备工作,已经beanFactoryPostProcessor的创建,已经完成




5.invokeBeanFactoryPostProcessors(beanFactory)  【执行beanFactoryPostProcessor】
    执行beanFactoryPostProcessor和beanDefinitionRegistryPostProcessor
    后置处理器的方法(对 beanFactory或 beanDefinitionRegistry做一些包装和处理)
    
    1.先执行 beanDefinitionRegistryPostProcessor
    	1.get 所有的 BeanDefinitionRegistryPostProcessor
    	
    	2.先执行 实现了 priorityOrdered 优先级接口的 BeanDefinitionRegistryPostProcessor的
    		post.processBeanDefinitionRegistry(registry)
    		
    	3.再执行 实现了 ordered接口的
    	
    	4.最后执行 啥优先级接口都没实现的 
    	
    2.再执行 beanFactoryPsotProcessor
    	1.get 所有的 BeanFactoryPostProcessor
    	
		2.先执行 实现了 priorityOrdered 优先级接口的 BeanFactoryPostProcessor的
			post.processBeanFactory(beanFactory)
			
		3.再执行 实现了 ordered接口的
		
		4.最后执行 啥优先级接口都没实现的 
		
		
	=========================================================================		
			beanFactory和 beanDefinitionRegistry 已经 完成处理了			
		
		
		
		    		
6.registerBeanPostProcessor(beanFactory);【注册BeanPostProcessor】 
    	(不同接口类型的BeanPostBeanProcessor,在 bean 创建前后执行时机和作用都不一样)
    	(BeanPostProcessor,
    	  DestructionAwareBeanPostProcessor,
    	  InstantiationAwareBeanPostProcessor,
    	  SmartInstantiationAwareBeanPostProcessor,
    	  MergerdBeanDefinitionPostProcessor【internalProcessor】
    	 )
    注册同样也是 按优先级 注册 并排序,加入到BeanPostProcessorList中去
    
 7.initMessagerSource  初始化注册messageSource组件(主要用来 读取 国际化配置文件的值)
 
 8.initApplicationEventMulticaster;  初始化事件派发器
 	1.从 beanFactory中创建获得,若没有 创建一个 SimpleApplicationEventMulticaster
 	2.将创建的 multicaster 加入到 beanFactory中,以便其他组件 自动注入
 	
 9.onRefresh(); 留给子容器(子类)
 	1.子类重写这个方法,在容器刷新的时候可以自定义逻辑
 	
 10.registerListeners();  注册监听器,并add 到 事件派发器中 让其管理
 	1.从容器中拿到所有的 ApplicaitonListener
 	2.将 每一个 listener 添加到 事件派发器中
	
==============================================================
		beanPostProcessor 已经创建了 , 事件派发器已经创建 , 
		部分普通方式注册的监听器已经创建并且 加入到 EventMulticaster中了
=========================================================================
	下面就是 bean的创建 以及 最后一部分监听器的创建并加入到 事件派发器中了
 	
	
	
	
 11.finishbeanFactoryInitialization(beanFactory)  初始化所有 剩下的 单实例bean
 	1.beanFactory.preInstantiateSingletons();  初始化所有的剩下的单实例bean
 		1.获取容器中所有的 BeanDefinition,依次初始化和创建的对象
 		
 		2.如果bean不是抽象的,不是懒加载的,是单实例的
 			1.判断是否是 工厂bean,若是,那么调用它的 getObject创建对象,创建完成后,将它加入到beanFactory的缓存中
 			  下一次beanFactory.getBean()就直接从缓存中拿
 			
 			2.若不是工厂bean,利用 beanFactory.getBean(beanName);创建对象
 				1.getBean(beanName); ioc.getBean();
 				
 				2.doGetBean();
 				
 				3.先从缓存中保存的单实例获取Bean(beanFactory中的map保存单实例对象)
 				  从pricate final Map<String,Object> singletonObjects = new ConcurrenrHashMap<String,Object> 中 获取单实例bean
 				  
 				4.缓存中获取不到,开始bean的创建流程(前提有其beanDefinition)
 				
 				5.标记当前 bean 已被创建
 				
 				6.获取 bean的定义信息
 				
 				7.获取当前 bean依赖的 其他bean;如果有,先创建依赖bean的单实例bean对象
 				
 				8.启动单实例的创建流程
 					1.createBean(beanName,mbd,args);
 					
 					2.Object bean = resolveBeforeInstantiation(beanName,mbdToUse)
 						让 BeanPostProcessor 先拦截返回代理对象;
 						InstantiationAwareBeanPostProcessor 提前执行;
 						先触发: postProcessBeforeInstantiation();
 						若有返回值: 触发 postProcessAfterInstantiation();
 						
 					3.若前面的没有 
 					
 					4.Object beanINstance = doCreateBean(beanName,mbdToUse,args);
 						1.创建 Bean实例; createbeanInstance(beanName,mbd,args);
 						  	利用工厂方法,或者自己写的 构造器筹建处 bean实例
 						  	
 						2.applyMergedBeanDefinitionPostProcessor(mbd,beanType,beanName)
 						  	调用 MergedBeanDefinitionPostProcessor的 postProcessMergedBeanDefinition(mbd,beanType,beanName)
 						  	
 						3.【bean属性赋值】 populateBean(beanName,mbd,instanceWrapper)
 							1.拿到 InstantiationAwareBeanPostProcessor后置处理器
 							  	postProcessAfterInstantiation();
 							  	
 							2.拿到 InstantiationAwareBeanPostProcessor后置处理器
 							  	postProcessPropertyValues();
 			==============================================================
 								bean赋值之前
 								
							3.应用 Bean属性的值;为属性利用 setter方法 赋值
								applypropertyValues(beanName,mbd,bw,ms)
            =======================================================
            					bean赋值完成
            					
            			4.【Bean的初始化】initializeBean()
            				1.【执行Aware接口的方法】 invokeAwareMethods(beanName,bean),执行 xxxAware接口的回调方法
            					
            				2.【执行bean后置处理器链】  applyBeanPostprocessorsBeforeInitialization();
            							beanPostProcessor.postprocessorBeforeInitialization();
            							
            				3.【执行初始化方法】 invokeinitMethods(beanName,wrapperedBean,mdb);
            							1.是否实现 InittializingBean接口
            							2.是否自定义 初始化方法
            							
            				4.【执行bean后置处理器链】 applyBeanPostprocessorsBeforeInitialization();
            							beanPostProcessor.postprocessorAfterInitialization();		
            									
						5.注册 bean的 销毁方法
								
					5.将创建的bean 添加到 缓存中,singletonObjects(beanFactory中的一个map)
					  ioc容器 beanFactory中就是这些map;很多map保存了 单实例bean,环境信息....
					  beanFactory.getBean()即是从这个map中获取对象,(没有)那么就是创建对象,创建完成后,
					  还得把单实例bean,添加到缓存中,下次beanFactory.getBean()就会从缓存中get bean
							  
					6.所有 bean创建完成后,并添加到缓存后,检查所有bean是否实现了SmartInitializingSingleton接口
					  若是,执行其 afterSingletonsInstantiated()方法,遍历所有bean的@EventListener注解
					  生成对应的 Listener,并将其添加到 事件多播器中去管理
							  
12.finishRefresh();实现 BeanFactory初始化创建工作,ioc容器创建完成
	1.initLifecycleProcessor();初始化和生命周期有关的 后置处理器:LifecycleProcessor
	  默认容从器中找是否有lifecycleProcessor的组件
	  【LifecycleProcessor】;若无,new 一个加到 容器中
	  写一个LifecycleProcessor的实现类,可以在BeanFactory
	  		void onRefresh();
	  		void onClose(); 时执行
	  		
	2. getLifecycleProcessor().onRefresh()
	   拿到前面的 生命周期后置处理器;回调 onRefresh()方法
	   
	3. publishEvent(new ContextRefreshedEvent(this)); 发布容器刷新完成时间

没有web.xml,以及springmvc,spring的配置文件的时候,如何注册servlet,listener,filter的问题(servlet3.0以及springmvc如何处理异步请求的问题(tomcat的线程池有限,例如一个请求占用一个线程池很久,那么我们在此从开一个线程池去处理业务逻辑,这样tomcat的主线程池就可以立马得到释放)

**ioc步骤的简要几步**

1.创建 beanFactory 和 beanDefinitionRegistry

2.beanPostProcessor的插件,事件派发器的创建,普通注册方式的监听器的插件,并 -> 事件派发器

3.剩下单实例bean的创建

1.工厂bean -> getObject() ->缓存
2.非工厂
	1.返回一个代理对象(后置处理器,可能有或无)
	2.若无
		1.创建出 bean实例
		2.bean的属性赋值(InstantiationAwareBeanPostProcessor后置处理器)
		3.bean初始化
			1.若bean是 aware接口,执行接口方法
			2.后置处理器链 before方法
			3.init()
			4.后置 after方法

4.bean实例 -> 缓存

5.剩下监听器 -> 派发器(后置处理器检查bean是否是 SmartInitializingSinglon接口)

6.实现BeanFactory初始化创建工作,ioc容器创建完成

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值