spring框架终极版

视频链接

spring相关文章链接

Spring事件驱动

全面了解SpringBoot拦截器

Bean的生命周期

生产–使用–销毁

生产
loadBeanDefinitions加载bean定义。用xml,注解扫描等方式找到bean的定义放到beanDefinitionMap中
在这里插入图片描述
遍历集合beanDefinitionMap,通过createBean创建Bean对象
在这里插入图片描述
构造对象,填充属性,初始化实例,注册销毁
1-构造对象
createBeanInstance方法,利用反射机制,从‘bean定义’中的BeanClass拿到这个类的构造方法,规则:只有一个就拿那个,有多个时优先拿@AutoWired注解的构造方法,无注解的拿无参构造,否则报错。对于有参构造,准备参数,在bean的单例池中,根据class找,如果有多个实例,则根据参数名进行匹配

2-填充属性
通过populateBean方法为Bean内部所需的属性值进行赋值填充,通常为@AutoWired注解的变量,通过三级缓存机制进行注入

3-初始化实例
initializeBean初始化Bean对象
初始化容器相关的信息,通过invokeAwareMethods方法,为实现了各种Aware接口的Bean设置诸如BeanName,beanFactory等容器信息

在这里插入图片描述
通过invokeInitMethods方法执行Bean的初始化方法,用户通过实现initializingBean的接口而实现的afterPropertiesSet方法
在这里插入图片描述
继续会执行initMethod
在这里插入图片描述
在这里插入图片描述
在执行初始化方法之前及之后,需要对bean后置处理器BeanPostProcessors进行处理,通过applyBeanPostProcessorBeforeInitialization以及applyBeanPostProcessorAfterInitialization分别初始化之前和之后的各种Bean的后置处理,包括负责aop处理的AnnotationAwareAspectJAotoproxyCreator,负责构造后@PostConstruct和销毁前@PreDestory处理的InitDestotyAnnotationBeanPostProcessor等,以及用户通过实现BeanPostProcessor接口的自定义处理器

用户通过实现BeanPostProcessor接口自定义处理器
在这里插入图片描述
4–注册销毁
通过注册销毁registerDisposableBean方法,将实现了销毁接口DisposableBean的Bean进行注册,这样在销毁时就可以执行destory方法了

通过以上4步,bean创建好了,用addSingleton方法将bean放入单例池singletonObjects中就可以获取和使用了

使用
销毁
在销毁前要执行“销毁前处理器”PostProcessBeforeDestruction,这里就会执行bean中的@preDestory注解的方法,然后通过destoryBeans方法逐一销毁所在的bean

run之后会经历4个阶段
1.服务构建
2.环境准备
3.容器创建
4.填充容器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上下文初始化中:容器ID,警告日志处理,日志监听 都在这里创建

一.基础知识

1.spring 是什么?
容器,有良好的生态,IOC,AOP

2.IOC

IOC:控制反转,把对象的创建,赋值,管理工作都交给代码之外的容器实现
IOC的技术实现
DI:依赖注入,只需要在程序中提供要使用的对象的名称就可以,至于对象如何在容器中创建,赋值,查找都由容器内部实现。
spring使用的di实现了IOC的功能,spring底层创建对象,使用的是反射机制。
spring是一个容器,管理对象,给属性赋值,底层是反射创建对象。

DI的实现有两种:
1.在spring的配置文件中,使用标签和属性完成,叫做基于XML的DI实现
2.使用spring中的注解,完成属性赋值,叫做基于注解的DI实现

DI的语法分类:
1.set注入(设置注入):spring要调用类的set方法,在set方法可以实现属性的赋值。
2.构造注入,spring调用类的有参数构造方法,创建对象。在构造方法中完成赋值。

基于注解的DI
概念:通过注解完成Java对象创建,属性赋值

使用注解的步骤:
1.加入maven依赖 spring-context,在加入spring-context的同时,间接加入spring-aop依赖。
使用注解必须使用spring-aop依赖

2.在类中加入spring的注解(多个不同功能的注解)
3.在spring的配置文件中,加入一个组件扫描器的标签,说明注解在项目中的位置

Bean的定义有xml和注解两种方式
在这里插入图片描述
3.bean
在这里插入图片描述
通过BeanDefinitionReader读取信息,生成BeanDefinition,也就是bean的定义信息,然后根据这些信息,利用反射生成bean对象
在这里插入图片描述
PostProcessor
BeanPostProcessor

public interface BeanPostProcessor {
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

BeanPostProcessor原理
该接口我们也叫后置处理器,作用是在Bean对象在实例化和依赖注入完毕后,在显示调用初始化方法的前后添加我们自己的逻辑。注意是Bean实例化完毕后及依赖注入完成后触发的。

首先-初始化bean—>检查容器中是否存在BeanPostProcessor,
如果存在就调用postProcessBeforeInitialization方法
—>如果返回null(或者所有的BeanPostProcessor执行完毕)
---->执行bean的初始化方法
---->再次判断容器中是否存在BeanPostProcessor
—>如果存在就调用postProcessAfterInitialization方法
—>如果返回null(或者所有的BeanPostProcessor执行完毕)
—>运行结束
如果一开始容器中就没有 BeanPostProcessor,那么就会直接支持bean的初始化方法

BeanFactoryPostProcessor

@FunctionalInterface
public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}

其子类 BeanDefinitionRegistryPostProcessor

二.常见问题

1.循环依赖

在这里插入图片描述
实例化和初始化是分开执行的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(5)在对象对外暴露的时候,如何准确的给出原始对象或代理对象,因为正常点的代理对象的创建实在BeanPostProcessor的后置处理方法中,在解决循环依赖问题的时候还没有执行到那个地方?
所以此时需要lambda表达式了,类似一种回调机制,在确定对外暴露的时候,就唯一性的确定到底是代理对象还是原始对象,这就是为什么不把对象放到二级缓存中,而是通过三级缓存Lambda表达式的表示方式来执行了

在这里插入图片描述
三级缓存不能解决的循环依赖问题
在这里插入图片描述

谈谈IOC的理解
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
AOP
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

refresh

Spring之refresh的12个步骤

refresh 是 AbstractApplicationContext 中的一个方法,负责初始化 ApplicationContext 容器,容器必须调用 refresh 才能正常工作。它的内部主要会调用 12 个方法,我们把它们称为 refresh 的 12 个步骤

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			//为进行刷新准备此上下文
			prepareRefresh();

			// 告诉子类刷新内部bean工厂。
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 准备bean工厂以便在此上下文中使用。
			prepareBeanFactory(beanFactory);

			try {
				// 允许在子类上下文中对bean工厂进行后处理。
				postProcessBeanFactory(beanFactory);

				//调用注册为bean的工厂处理器
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册用来拦截bean创建的bean处理器。
				registerBeanPostProcessors(beanFactory);

				// 初始化此上下文的消息源。
				initMessageSource();

				// 初始化事件派发器Multicaster
				initApplicationEventMulticaster();

				//初始化指定上下文中的其他bean
				onRefresh();

				// 检查侦听器bean并注册它们
				registerListeners();

				// 实例化所有剩余的(非惰性init)singleton。
				finishBeanFactoryInitialization(beanFactory);

				// 最后一步:发布相应的事件。
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// 销毁已创建的singleton以避免挂起资源。
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				//重置Spring核心中的常见内省缓存,因为我们可能再也不需要单例bean的元数据了
				resetCommonCaches();
			}
		}
	}

在这里插入图片描述
在这里插入图片描述
springboot监听流程
在这里插入图片描述
什么是 Actuator
Spring Boot Actuator 模块提供了生产级别的功能,比如健康检查,审计,指标收集,HTTP 跟踪等,帮助我们监控和管理Spring Boot 应用。

这个模块是一个采集应用内部信息暴露给外部的模块,上述的功能都可以通过HTTP 和 JMX 访问。

因为暴露内部信息的特性,Actuator 也可以和一些外部的应用监控系统整合(Prometheus, Graphite, DataDog, Influx, Wavefront, New Relic等)。

这些监控系统提供了出色的仪表板,图形,分析和警报,可帮助你通过一个统一友好的界面,监视和管理你的应用程序。
/health 端点
当我们开启health的健康端点时,我们能够查到应用健康信息是一个汇总的信息,访问
http://127.0.0.1:10111/actuator/health时,我们获取到的信息是{“status”:“UP”},status的值还有可能是 DOWN
健康信息包含磁盘空间、redis、DB,启用监控的这个spring boot应用确实是连接了redis和oracle DB,actuator就自动给监控起来了,确实是很方便、很有用。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
解决跨域
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值