# Spring源码解析 **Repository Path**: Dkui97/spring_source_code_analysis ## Basic Information - **Project Name**: Spring源码解析 - **Description**: Spring源码解析 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-05-16 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Spring源码解析 ## 介绍 Spring源码解析 ## Spring碎片目录 ### 组件注册 1. @Bean ``` @Bean:给容器中注入组件 意思是@Bean明确地指示了一种方法,什么方法呢——产生一个bean方法,并且交个spring的ioc容器;从这里我们就明白了为啥@Bean是放在方法的注解上的,因为很明确的告诉被注解的方法,给我产生一个bean,然后交给spring的ioc容器。 ``` 2. @SuppressWarnings("resource") ``` 这个批注可以取消一些特定代码段中的警告,比如你看到警告,你查了一下,发现他不是问题,可是你为了好看又不想让他报警,就可以加这个批注。 ``` 3. @Test ``` 注解是JUnit测试的基础 ``` 4. @Filter ``` @Filter 指定过滤规则 - FilterType.ANNOTATION 按照注解方式 - FilterType.ASSIGNABLE_TYPE,按照给定的类型 - FilterType.ASPECTJ,使用ASPECTJ表达式 - FilterType.REGEX,正则表达式 - FilterType.CUSTOM,自定义规则 - //excludeFilters = Filter[],指定扫描的时候按照什么规则排除那些组件 - //includeFilters = Filter[].指定扫描时候只需要包含那些组件 **例子** - @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class}), //指定排除规则 例子去掉了Controller Service - @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {BookService.class}), //FilterType.ASSIGNABLE_TYPE,按照给定的类型 - @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class}), //FilterType.CUSTOM,自定义规则 ``` 5. @Scope:设置组件的作用域 ``` - * prototype : 多实例的,ioc容器启动并不会去调用方法创建对方放容器中, - 每次获取的时候才会调用方法创建对象 - * singleton : 单实例的(默认值),ioc容器启动会调用方法创建对象ioc容器中 - 以后每次获取就是直接从容器(map.get())中拿 - * request : 同一个请求创建一个实例 - * session : 同一个session创建一个实例 ``` 6. @Lazy:懒加载 ``` * 懒加载 * 单实例bean,默认再容器启动的时候创建对象 * 懒加载,容器启动不创建对象,第一次使用(获取)bean创建对象,并初始化 ``` 7. @Conditional:按照一定的条件进行判断,满足条件给容器注册bean ``` //1.能获取到ioc使用的beanfactory ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //2.获取到类的加载器 ClassLoader classLoader = context.getClassLoader(); //3.获取当前环境信息 Environment environment = context.getEnvironment(); //4.获取到Bean定义的注册类 BeanDefinitionRegistry registry = context.getRegistry(); ``` 8. @Import:快速给容器中导入组件 ``` * @Import 【快速给容器中导入组件】 * 1.@Import(要导入到容器的组件),容器中就会自动注册这个组件,id是默认全类名 * 2.ImportSelector:返回需要导入的组件的全类名数组 * 3.ImportBeanDefinitionRegistrar:它里面有个方法叫registerBeanDefinitions,通过调用这个方法可以自己给容器添加组件, * AnnotationMetadata 当前类的一直注解信息 * BeanDefinitionRegistry Bean定义的注册类 * 4.使用Spring提供的FactoryBean(工厂bean) * 1.默认获取到的是工厂bean调用getObject创建对象 * 2.要获取工厂bean本身,我们需要给id前面加一个& * &colorFactoryBean ``` ### 生命周期 1.@Bean指定初始化和销毁方法 ``` * @User: fisherman * @Date: 2020/5/20 11:09 * * bean的生命周期 * bean创建---初始化---销毁过程 * 容器管理bean的生命周期 * 我们可以自定义初始化和销毁方法,容器再bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁过程 * * 构造(对象创建) * 单实例:在容器启动的时候创建对象 * 多实例:在每次获取的时候创建对象 *BeanPostProcessor.postProcessBeforeInitialization在初始化之前工作 *初始化 * 对象创建完成,并赋值好,调用初始化方法 *BeanPostProcessor.postProcessAfterInitialization:在初始化之后工作. * 销毁 * 单实例:容器关闭的时候 * 多实例:容器不会管理这个bean;容器不会调用销毁方法 * * * * * 1。指定初始化和销毁方法 * 通过@bean注解 指定的方法(xml中配置) init-method="" destroy-method="" * 2.通过让Bean实现InitializingBean(定义初始化逻辑) * DisposableBean(定义销毁逻辑) * 3.可以使用JSR250 * @PostConstruct ,在bean创建完成并且属性赋值完成,来执行初始化方法 * @PreDestry ,在容器销毁bean之前通知我们进行清理工作 * 4.BeanPostProcessor 【interface】,bean的后置处理器 * 在bean初始化前后进行一些处理工作 * postProcessBeforeInitialization:在初始化之前工作 * postProcessAfterInitialization:在初始化之后工作. * * BeanPostProcessor原理 * 遍历得到容器中所有的BeanPostProcessor,挨个执行postProcessBeforeInitialization, * 一但返回null,跳出for循环,不会执行遍历得到容器中所有的BeanPostProcessor.postProcessorsBeforeInitialization * populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值的 * initializeBean { * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); * invokeInitMethods(beanName, exposedObject, mbd);执行自定义初始化 * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); * } * Spring底层对BeanPostProcessor使用 * bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async等 ``` ### 组件赋值 1.@Value赋值 ``` * //使用@Value赋值 * //1,基本数据 * //2.可以写${};取出配置文件的值(运行在环境变量里面的值) * //使用@PropertySource读取外部配置文件中的k/v保存到运行的环境变量中; //加载完外部配置文件以后使用${}取出配置文件的值 ``` ### 自动装配 ```$xslt * @User: fisherman * @Date: 2020/5/22 9:03 * * 自动装配 * Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值 * * 1.@Autowired 自动注入 * 1.默认优先按照类型去容器中找对应的组件 applicationContext.getBean(BookDao.class);//找到就赋值 * 2.如果找到多个相同类型的组件,再将属性名称作为组件的id去容器中查找 * applicationContext.getBean(“bookDao”) * 3.@Qualifier("bookDao"),使用@Qualifier指定需要装配的组件id,而不是属性名 * 4.自动装配默认一定将属性赋值好,没有就会报错, * 可以使用@Autowired(required=false); * 5.@Primary,让spring进行自动装配的时候,默认使用首选的bean * 也可以继续使用@Qualifier指定需要的bean的名字 * BookService{ * @Autowired * BookDao bookDao; * } * 2.spring还支持使用@Resource(JSR250)和@Inject(JSR330)【java规范注解】 * @Resource:可以和@Autowired一样实现自动装配功能,默认是按照组件名称进行装配的 * 没有能支持@Primary功能没有支持@Autowired(reqiured=false) * @Inject:需要导入javax.inject的包,和Autowired的功能一样,没有reqiured=false功能 * * @Autowired是Spring定义的; @Resource和@Inject都市java规范 * * AutowiredAnnotationBeanPostProcessor:解析完成自动按照功能 * * 3.@Autowired:构造器,参数,方法,属性;都是从容器中获取当前组件的值 * 1.标注在方法的位置 @Bean+方法参数,参数从容器中获取,默认不写@Autowired效果是一样的都能自动装配 * 2.标书在构造器 如果组件只有一个有参构造器,这个参数构造器的@Autowired可以省略,参数位置的组件还可以自动从容器中获取 * 3.放在参数位置 * 4.自定义组价想要使用spring容器底层的一些组件,(ApplicationContexe,BeanFactory,xxx) * 自定义实现xxxAware,在创建对象的时候,会调用接口规定的方法注入相关组价, * 把spring底层的组件注入到自定义的bean中, * xxxAware;功能使用xxxProcessor * ApplicationContextAware ==> ApplicationContextAwareProcessor * * *Profile * Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件功能 * * 开发环境,测试环境,生产环境 * 数据(/a)(/b)(/b) * * @Profile:指定组件在哪个环境的情况下才能被注册容器中,不指定,任何环境下都能注册这个组件 * 1.加了环境表示。只有这个环境被激活的时候才能注册到容器中,默认是default环境 * 2.写在配置类上,只有指定的环境的时候,整个配置类里面所有的配置才能生效 * 3.没有标注环境表示的bean在任何环境下都是加载的bean */ ``` ### AOP[动态代理] ``` /** * @User: fisherman * @Date: 2020/5/23 11:07 * * * AOP:【动态代理】 * 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式 * * 1,导入aop模块 spring aop [spring-aspects] * 2.定义一个业务逻辑类 【MathCalculator】,在业务逻辑运行的时候可以吧日志打印一下(方法之前,方法运行结束,方法出现异常) * 3.定义一个日志切面(LogAspects),切面类面的方法需要动态感知MathCalculator.div运行到哪里然后执行 * 通知方法: * 前置通知(@Before); logStart,在目标方法(div)运行之前 * 后置通知(@After); logEnd 在目标方法(div)运行之后 * 返回通知(@AfterReturning); logReturn 在目标方法(div)正常返回之后运行 * 异常通知(@AfterThrowing); logException 在目标方法(div)出现异常时运行 * 环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint.procced()) * 4.给切面类的目标方法标注何时何地运行(通知注解) * 5.将切面类和业务逻辑类(目标方法所在的类)都加入到容器中; * 6.必须告诉spring那个类是切面类(给切面类加上一个注解@Aspect) * 7.给配置类加@EnableAspectJAutoProxy【开启基于注解的aop模式】 * 在spring中的很多@Enablexxx; *aop三步曲 * 1.将业务逻辑组件和切面类都加入到容器中,告诉spring那个是切面类(@Aspect) * 2.切面类上的每一个通知方法上标注通知注解,告诉spring何时何地运行(切入点表达式) * 3.开启基于注解的aop模式:@EnableAspectJAutoProxy * * * *aop原理:【看给容器注入的什么组件,这个组件什么时间工作,这个是组件的功能是什么】 * @EnableAspectJAutoProxy; * * 1.@EnableAspectJAutoProxy是什么 * @Import(AspectJAutoProxyRegistrar.class),给容器中导入AspectJAutoProxyRegistrar * 利用AspectJAutoProxyRegistrar自定义给容器中注入bean * internalAutoProxyCreator = AnnotationAwareAspectJAutoProxyCreator * * 给容器中注册一个AnnotationAwareAspectJAutoProxyCreator *2.给容器中注册一个AnnotationAwareAspectJAutoProxyCreator是什么 * AnnotationAwareAspectJAutoProxyCreator * -》AspectJAwareAdvisorAutoProxyCreator * ->AbstractAdvisorAutoProxyCreator * ->AbstractAutoProxyCreator * implements SmartInstantiationAwareBeanPostProcessor,BeanFactoryAware * 关注后置处理器(在bean初始化完成前后做的事情),自动装配BeanFactory * *AbstractAutoProxyCreator.setBeanFactory() * AbstractAutoProxyCreator.后置处理器的逻辑 * * AbstractAdvisorAutoProxyCreator.seBeanFactory()->initBeanFactory() * * AnnotationAwareAspectJAutoProxyCreator.initBeanFactory() * * 流程: * 1.传入配置类,创建ioc容器 * 2.注册配置类,调用refresh()刷新容器 * 3.registerBeanPostProcessors(beanFactory,注册bean的后置处理器,来方便拦截bean的创建) * 1.先获取ioc容器中已经定义的需要创建对象所有BeanPostProcessor * 2.给容器加别的BeanPostProcessor * 3.优先注册了PriorityOrdered接口BeanPostProcessor * 4.在容器中注册实现了Order接口的BeanPostProcessor * 5.注册没实现优先级接口的BeanPostProcessor * 6.注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中 * 创建internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】 * 1.创建bean的实例 * 2.populateBean,给bean的各种属性赋值 * 3.initializeBean:初始化bean * 1.invokeAwareMethods(),处理Aware接口的方法回调 * 2.applyBeanPostProcessorBeforeInitialization()应用后置处理器的postProcessBeforeInitialization() * 3.invokeInitMethods()执行自定义的初始化反方法 * 4.applyBeanPostProcessorBeforeInitialization(),执行后置处理器的postProcessAfterInitialization() * 4.BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功,--》aspectJAdvisorsBuilder * 7.把BeanPostProcessor注册到的BeanFactory中 * beanFactory.addBeanPostProcessor(postProcessor) *======以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程====== * AnnotationAwareAspectJAutoProxyCreator =》InstantiationAwareBeanPostProcessor() * * 4.finishBeanFactoryInitialization(beanFactory),完成BeanFactory初始化工作,创建剩下的单实例bean * 1.遍历获取容器中所有bean,依次创建对象getBean(beanName) * getBean -》 doGetBean() -> getSingleton() -> * 2.创建bean * 【AnnotationAwareAspectJAutoProxyCreator在所有bean创建完成之前会有一个拦截,InstantiationAwareBeanPostProcessor,会调用postProcessBeforeInstantiation()】 * 1.先从缓存中获取bean,如果获取到,说明bean之前被创建过,直接使用,否则再创建 * 只要创建好的bean就会被缓存起来 * 2.createBean(); 创建bean AnnotationAwareAspectJAutoProxyCreator会在任何bean创建之前先尝试返回bean实例 * [BeanPostProcessor是在Bean对象创建完成初始化前后调用的] * [InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试使用后置处理器返回对象] * 1.resolveBeforeInstantiation(beanName,mbdToUse);解析BeforeInstantiation * 希望后置处理器在此能返回一个代理对象,如果能返回代理对象就使用,不能就继续 * 1.后置处理器先尝试返回对象 * bean = applyBeanPostProcessorsBeforeInstantiation; * //拿到所有的后置处理器,如果是InstantiationAwareBeanPostProcessor, * //就执行postProcessBeforeInstantiation * if(bean != null){ * bean = applyBeanPostProcessorsAfterInitialization(bean,beanName) * } * * 2.doCreateBean(beanName,mbdToUse,args);真正的去创建一个bean实例和3.6一样 * * AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】的作用 * 1.每一个bean创建之前,调用postProcessBeforeInstantiation(); * 关心MathCalculator和LogAspect的创建 * 1.判断当前bean是否在advisedBeans中,(保存了所有需要增强的bean) * 2.判断当前bean是否是基础类型的Advice,Pointcut.class.isAssignableFrom(beanClass) || * Advisor.class.isAssignableFrom(beanClass) || * AopInfrastructureBean.class.isAssignableFrom(beanClass); * 或者是否是切面,(@Aspect) * 3.是否需要跳过 * 1.获取增强器,(切面里面的通知方法)【List candidateAdvisors】 * 每一个封装的通知方法增强器是InstantiationModelAwarePointcutAdvisor; * 判断每一个增强器是否是AspectJPointcutAdvisor类型的:返回true * 2。永远返回false *2.创建对象 * PostProcessorsAfterInitialization * return wrapIfNecessary(bean,beanName,cacheKey);//包装需要的情况下 * 1.获取当前bean的所有增强器(通知方法) * 1.找到候选所有的增强器(找打那些通知方法需要切入当前bean方法的) * 2.获取到能在bean使用的增强器0 * 3.给增强器排序 * 2.保存当前bean在advisedBeans中, * 3.如果当前bean需要增强,只需要创建一个bean的代理对象 * 1.获取所有增强器(通知方法) * 2.保存到proxyFactory * 3.创建代理对象,Spring自动决定 * jdkDynamicAopProxy(config);jdk动态代理 * ObjenesisCglibAopProxy(config);cglib代理 * 4.给容器中返回当前组件使用cglib增强了的代理对象 * 5.以后容器获取到的就是这个组件代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程 *3.目标方法的执行 * 容器中保存组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx) * 1.CglibAopProxy.intercept();拦截目标方法的执行 * 2.根据ProxyFactory对象获取要执行的目标方法拦截器链 * Listchain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,targetClass); * 1.ListinterceptorList保存所有拦截器 * 一个默认的ExposeInvocationInterceptor 和 4个增强器 * 2.遍历所有的增强器,将其转化为Interceptor * registry.getInterceptors(advisor) * 3.将增强器转为List; * 如果是MethodInterceptor,直接加入集合中 * 如果不是,使用AdvisorAdapter将增强器转为Interceptor * 转换完成返回MethodInterceptor数组 * 3.如果没有拦截器链,直接执行目标方法 * 连接器链(每个通知方法又被包装为方法拦截器,利用MethodInterceptor机制) * 4.如果有拦截器链,把需要执行的目标对象,目标方法,拦截器链等信息创建一个CglibMethodInvocation对象 * 并调用Object retVal = mi.proceed() * 5.拦截器的触发过程; * 1.如果没有拦截器执行目标方法,或者拦截的索引和拦截器数组-1大小一样(指定到最后一个拦截器执行目标方法) * 2.链式获取每一个连接器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成后返回以后再执行 * 拦截器链的机制,保证通知方法与目标方法的执行排序 * * 总结: * 1.@EnableAspectJAutoProxy; 开启aop功能 * 2.@EnableAspectJAutoProxy 会给容器中注册一个组件AnnotationAwareAspectJAutoProxyCreator * 3.AnnotationAwareAspectJAutoProxyCreator是一个后置处理器 * 4.容器的创建流程 * 1.registerBeanPostProcessors()注册后置处理器 * 2.finishBeanFactoryInitialization()初始化剩下的单实例bean * 1.创建业务组件和切面组件 * 2.AnnotationAwareAspectJAutoProxyCreator拦截器组件的创建过程 * 3.组件创建完之后,判断组件是否需要增强 * 是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib) * 5.执行目标方法 * 1,代理对象执行目标方法 * 2,CglibAopProxy.intercept() * 1.得到目标方法的拦截器(增强器包装成拦截器MethodInterceptor) * 2.利用拦截器的链式机制,一次进入每一个拦截器进行执行 * 3.效果: * 正常执行:前置通知-》目标方法-》后置通知-》返回通知 * 出现异常:前置通知-》目标方法-》后置通知-》异常通知 * * */ ``` ### 声明事务 ```$xslt * 声明事务: *

* 环境搭建: * 1.导入相关依赖 * 数据源,数据库驱动,Spring-jdbc模块 *

* 2.配置数据源,jdbcTemplate(Spring提供的简化数据库操作的工具)操作数据 * 3.给方法上标注@Transactional表示当前方法是一个事务方法 * 4.@EnableTransactionManagement开启基于注解的事务 * @Enablexxx *5.配置事务管理器来控制事务 * @Bean * public PlatformTransactionManager transactionManager() * * 原理: * 1.@EnableTransactionManagement * 利用TransactionManagerConfigurationSelector给容器中导入组件 * 导入两个组件 * AutoProxyRegistrar * ProxyTransactionManagementConfiguration * 2.AutoProxyRegistrar: * 给容器注册一个InfrastructureAdvisorAutoProxyCreator组件 * InfrastructureAdvisorAutoProxyCreator * 利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器)代理对象执行方法利用拦截器链进行调用 * 3.ProxyTransactionManagementConfiguration做什么? * 1,给容器中注册事务增强器 * 1,事务增强拦截器要用的事务的注解信息;AnnotationTransactionAttributeSource解析事务 * 2,事务拦截器: * TransactionInterceptor;保存事务属性信息,事务管理器 * 他是一个MethodInterceptor, * 在目标方法执行的时候 * 执行拦截器: * 事务拦截器: * 1.先获取事务相关的属性 * 2.在获取PlatformTransactionManager如果事先没有添加指定任何transactionmanger * 最终会在容器中获取一个PlatformTransactionManager * 3.执行目标方法 * 如果异常,获取到事务任务管理器,利用事务管理回滚操作 * 如果正常,利用事务管理器,提交事务 * ``` ####拓展原理 ``` /** * @User: fisherman * @Date: 2020/5/28 9:34 * * 拓展原理: * Bean * BeanFactoryPostProcessor :bean的后置处理器,bean创建对象初始化前后进行拦截工作的 * BeanFactoryPostProcessor:beanFactory的后置处理器 * 在beanFactory标注初始化之后调用,所有的bean配置已经保存加载到beanFactory,但是bean的实例化还没有创建 * * 1.ioc容器创建对象 * 2.invokeBeanFactoryPostProcessors(beanFactory)执行BeanFactoryPostProcessors * 如何找到所有的BeanFactoryPostProcessors并执行他们的方法 * 1.直接BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们方法 * 2.在初始化创建其他组件前面 * 2.BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor * postProcessBeanDefinitionRegistry(); * 在所有bean定义信息将要被加载,bean实例还未创建 * * 优先于BeanFactoryPostProcessor执行, * 利用BeanDefinitionRegistryPostProcessor给容器中再添加一些组件; * * 原理 * 1.ioc创建对象 * 2.refresh()-》invokeBeanFactoryPostProcessors(beanFactory) * 3.从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件,一次触发所有的 * 1.依次触发所有的postProcessBeanDefinitionRegistry()方法 * 2.再来触发postProcessBeaFactory()方法BeanFactoryPostProcessor * 4.再来从容器中找到BeanFactoryPostProcessor组件,然后依次触发postProcessBeanFactor * * 3.ApplicationListener:监听容器中发布的事件,事件驱动模型开发 * public interface ApplicationListener * 监听ApplicationEvent及其下面的子事件 * * 步骤: * 1.写一个监听器监听某个事件(ApplicationEvent以及子类) * @EventListener * 原理:使用EventListenerMethodProcessor处理来处理来解析方法上的@EventListener * * 2.把监听器加入到容器 * 3.只要容器中有相关事件发布,我们就监听这个事件 * ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件 * ContextClosedEvent:关闭容器会发布这个事件 * 4.发布一个事件 * * 原理: * ContextRefreshedEvent,IOCTest_Tex$1[source=我发布时间],ContextClosedEvent * 1.ContextRefreshedEvent事件: * 1.容器创建对象:refresh() * 2.finishRefresh()容器刷新完成会发布ContextRefreshedEvent事件 * 2.自己发布事件 * 3.容器关闭会发布ContextClosedEvent * 【事件发布流程】 * 3.publishEvent(new ContextRefreshedEvent(this)) * 事件发布流程 * 1.获取事件的多播器(派发起) getApplicationEventMulticaster() * 2.multicastEvent派发事假 * 3.获取到所有ApplicationListener * for(final ApplicationListenerlistener:getApplicationListeners(event,type)) * 1.如果有Executor,可以支持使用Executor进行异步派送 * Executor executor = getTaskExecutor(); * 2.否则,同步的方式直接执行listener方法:invokeListener(listener,event) * 拿到listener回调onApplicationEvent方法 * * 【事件多播器(派发器)】 * 1.容器创建对象:refresh() * 2.initApplicationEventMulticaster();初始化ApplicationEventMulticaster; * 1.先去容器中找有没有id=“applicationEventMulticaster”的组价 * 2.如果没有this.applicationEventMulticaster * 并且加入到容器中,我们就可以在其他组价要派发事件,自动注入这个applicationEventMulticaster * 【容器中有哪些监听器】 * 1.容器创建对象:refresh() * 2.registerListeners() * 从容器中拿到所有的监听器,把他们注册到applicationEventMulticaster中 * String[]listenerBeanNames =getBeanNamesForType(ApplicationListener.class,true,false) * //listener注册到applicationEventMulticaster中 * getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName) * * SmartInitializingSingleton原理 -》afterSingletonsInstantiated() * 1.ioc容器创建对象并refresh() * 2.finishBeanFactoryInitialization(beanFactory)初始化剩下的单实例bean * 1.先创建所有的但实例化bean;getBean(); * 2.获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的 * 如果是就调用afterSingletonsInstantiated() */ ``` ####Spring的容器源码 ``` Spring的容器refresh()【创建刷新】 1.preparefresh()算题前的预算处理 1.initPropertySources()初始化一些属性设置,子类自定义个性化的属性设置方法 2.getEnvironment().validateRequiredProperties();校验属性的合法等 3.earlyApplicationEvents=new LinkedHashSet();保存容器中的一些早期事件 2.obtainFreshBeanFactory()获取BeanFactory; 1.refreshBeanFactory(),刷新BeanFactory 创建一个this.beanFactory=new DefaultListableBeanFactory(); 设置id 2.getBeanFactory();返回刚才的GenericApplicationContext创建的eanFactory对象 3.将创建的BeanFactory【DefaultLostableBeanFactory】返回 3.prepparBeanFactory(beanFactory);BeanFactory的需准备工作(beanFactory进行一些设置) 1.设置beanFactory的类加载器,支持表达式解析器 2.添加部分BeanPostProcessor【ApplicationContextAwareProcessor】 3.设置忽略的自动装配的接口EnvironmentAware,EmbeddedValueResolverAware,xxx 4.注册可以解析的自动装配,我们能直接在任何组件中注入: BeanFactory,ResourceLoader,applicationEventPubkisher,applicationContext 5.添加beanPostProcessor【ApplicationListenerDetector】 6.添加编译时的AspectJ; 7.给BeanFactory中注册一些能用的组件 environment【ConfigurableEnvironment】 systemProperties【Map】 systemEnvironment【Map】 4.postProcessBeanFactory(beanFactory);BeanFactory准备工作完成进行的后置处理工作 1.子类通过重写这个方法来在BeanFactory创建并准备完成以后做进一步的设置 ===================以上是BeanFactory的创建以及预准备工作====================================== 5.invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessor; BeanFactoryPostProcessor;BeanFactory的后置处理器,在beanFactory标准初始化后执行的 两个接口:BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor 1,执行BeanFactoryPostProcessor的方法 先执行BeanDefinitionRegistryPostProcessor 1.获取所有的BeanDefinitionRegistryPostProcessor 2.看先执行实现了PriorityOrdered优先级接口BeanDefinitionRegistryPostProcessor postProcessor.postProcessBeanDfinitionRegistry(registry) 3,在执行实现了Ordered顺序接口的beanDefinitionRegistryPostProcessor; postProcessor.postProcessBeanDfinitionRegistry(registry) 4. 最后执行没有实现任何接口的的BeanDefinitionRegistryPostProcessor postProcessor.postProcessBeanDfinitionRegistry(registry) 在执行BeanFactoryPostProcessor方法 1.获取所有的BeanFactoryPostProcessor 2.看先执行实现了PriorityOrdered优先级接口BeanFactoryPostProcessor postProcessor.BeanFactoryPostProcessor(registry) 3,在执行实现了Ordered顺序接口的BeanFactoryPostProcessor; postProcessor.BeanFactoryPostProcessor(registry) 4. 最后执行没有实现任何接口的的BeanFactoryPostProcessor postProcessor.BeanFactoryPostProcessor(registry) 6,registerBeanPostProcessors(beanFactory);注册BeanPostProcessor(Bean的后置处理器)【intercept bean creation】 不同接口类型的BeanPostProcessor,在bean创建前后执行时机是不一样的 BeanPostProcessors, DestructionAwareBeanrocessor, SmartInstantiationAwareBeanPostProcessor MergedBeanDefinitionPostProcessor 1,获取所有的BeanPostProcessors;后置处理器都默认可以有PriorityOrdered,Ordered 2.先注册PriorityOrdered优先级接口的BeanPostProcessors 把每一个BeanPostPROCESSOR,添加到beanFactory中, beanFactory.addBeanPostProcessor(postProcessor) 3.再注册Ordered接口 4。最后注册没有实现任何优先级接口的 5.最终注册MergedBeanDefinitionPostProcessor 6.ApplicationListenerDetecortor。来在Bean创建完成的后检查是否是ApplicationLListener,如果是 applicationContext.addApplicationListener((ApplicationListener)bean); 7.initMessageSource(),初始化MessageSource 组件(做国际化功能,消息绑定,消息解析) 1.获取BeanFactory 2.看容器中是否有id为messageSource的,类型是MessageSource的组件 如果有赋值给messsageSource,如果没有自己创建一个DelegatingMessageSource MessageSource:取出国际化配置文件中某个key的值,能按照区域信息获取 3.把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME,this。messageSource) messageSource.getMessage(String code,Object[] args,String defaultMessage,Locale locale); 8. initApplicationEventMulticaster();初始化事件派件发器 1.获取BeanFactory 2.从BeanFactory中获取applicationEvenEventMulticaster的ApplicationEventMulicaster 3.如果上一步没有配置,创建一个SimlieApplicationEventMulticaster 4。将创建ApplicationEventMultiocaster 9.0nRefresh();留给子容器(子类) 1.子类重写这个方法,在容器刷新的时候可以自定义逻辑 10.registerListeners(),给容器中将所有的项目里面ApplicationListtener 1,从容器中拿到所有的ApplicationListener 2.将每个监听器添加到事件派发器中 getApplicationEventMulticaster().addAppllicationListenerBean(listenerBeanName) 3.派发之前步骤产出的事件 11.finishBeanFactoryInitialization(beanFactory);初始化所有剩下对的单实例bean 1.beanFcatory.perInstantiateSingletons();初始化剩下的单实例bean 1.获取容器中所有的bean,依次进行初始化和创建对象 2.获取bean的定义信息,RootBeanDefinition 3.Bean不是抽象的,不是抽象的,是单实例,是懒加载 1.判断是否是FactoryBean;是否是实现FactoryBean接口的bean 2.不是工厂bean,利用getBean(beanName);创建对象 0.getBean(beanName);ioc.getBean() 1.doGetBean(name,null,null,false) 2.先获取缓存中的单实例bean,如果能获取说明这个bean之前被创建过(所有创建过单实例bean都会被缓存起来) 3。缓存中获取不到,开始bean的创建对象流程 4.标记当前bean已经被创建 5。获取bean的定义信息 6.当前bean依赖的其他bean,如果有按照getBean()把依赖的bean创建起来 7.启动单实例bean创建流程 1.createBean(beanName,mbd,args); 2.Object bean= resolveBeforeInstantiation(beanName,mbdToUse);让beanPostProcessor先拦截返回代理对象 InstantionAwareBeanPostProcessor.提前执行; 先触发:postProcessBeforeInstantation(); 如果有返回值,触发postProcessAfterInitialization(); 3.如果前面的InstantionAwareBeanPostProcessor没有返回代理对象; 4.Object beanInstance=doCreateBean(beanName,mbdToUse,args);创建bean 1.创建bean实例createBeanInstance(beanName,mbd,args) 利用工厂方法或对象的构造器,创建bean实例 2.applyMeregedBeanDefinitionPostProcessors(mbd,beanType,beanName); 调用MeregedBeanDefinitionPostProcesser bdp.postProceessMergedBeanDefinition(mbd,beanType,beanName) 3.[bean属性赋值]populatebBean(beanName,mbd,instanceWrapper) 赋值之前 1.拿到instantionAwareBeanPostProcessor后置处理器 postProcessAfterInstantiation(); 2.拿到InstantiationAwareBeanPostPProcessor后置处理器 postProcessPropertyValues() =====赋值之前==== 3.应用bean属性的值;为属性利用setter等方法赋值 applyPropertyValues(beanName,mbd,bw,pvs); 4.【bean初始化】initializeBean(beanName,exposedObject,mbd); 1.【执行Aware接口方法】invkeAwareMethods(beanNamem,bean);执行***Aware接口方法 beanNameAware\BeanClassLoaderAware\BeanFactoryAware 2.【执行后置处理器方法】applyBeanPostProcessorBeforeInitialization(wrappedBean,beanName) BeanPostProcessor.postProcessBeforeInitialization(); 3.[执行初始化方法]invokInitMethids(beanName,wrappedBean,mbd) 1.是否是initializingBean接口实现;执行接口规定的初始化 2.是否定义初始化方法 4.【执行后置处理器初始化之后】applyBeanPostProcessorsAfterInitialization; BeanPostProcessor.postProcessAfterInitialization(); 5.注册bean销毁方法 5.将创建的bean添加到singletonObjects ioc容器就是这些Map,很多map里面保存单实例bean,环境信息 所有bean都利用getBean创建完成之后 检查所有的bean是否是SmartInitializingSingleton接口的:如果是,就执行 afterSingletonsInstantiated(); 12.finishRefresh();完成beanFactory的初始化创建工作,ioc容器就创建完成 1,initLifecylePrecessor(),初始化和生命周期相关的后置处理器,LifecycleProcessor 默认从容器中找是否也LifecycleProcessor的组件 写一个LifecycleProcessor的实现类 可以beanFactory的拦截 void onRefresh(); void onClose(); 2.getLifecyleProcessor().onRefresh(); 拿到前面定义的生命周期处理器(beanFactory)回调onrefresh(); 3.publishEvent(new ContextRefreshedEvent(this)) 发布容器刷新完成事件 4.iveBeansView.registerApplicationContext(this); =========总结======= 1.Spring容器在启动的时候,先会保存所有注册进来的bean的定义信息 1,xml注册bean 《bean》 2.注释注册bean,@Service,@Component,@Bean 2.spring容器会合适时机创建这些bean 1.用到这个bean的时候,利用getBean创建bean,创建好以后保存在容器中 2.统一创建剩下所有bean的时候, finishBeanFactoryInitialization() 3.后置处理器,BeanPostProcessor 1.每一个bean创建完成,都会使用各种后置处理器进行处理,来增强bean的功能 AutowiredAnnotationBeanPostProcessor:处理自动注入、 AnnotationAwareAspectJAutoProxyCreator:来做aop功能 xxx。。。 AsyncAnnotationBeanPostProcessor 4,事件驱动模型 ApplicationListener,事件监听 ApplicationEventMulticaster;事件派发 ``` #### 安装教程 1. xxxx 2. xxxx 3. xxxx #### 使用说明 1. xxxx 2. xxxx 3. xxxx #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 码云特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)