Spirng的生命周期和自动装配

@Bean指定初始化和销毁方法

Bean的生命周期:
	bean的创建 ---》初始化 --- 》销毁的过程
	容器来管理Bean的生命周期;我们可以自定义初始化和销毁方法;容器在进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
	构造(对象创建)
		单实例:在容器启动的时候创建对象
		多实例:在每次获取的时候创建对象
	初始化:
			对象创建完成,并赋值好,调用初始化方法。。。
	销毁:
			单实例:容器关闭的时候
			多实例:容器不会管理这个Bean;容器不会调用销毁方法
	1、指定初始化和销毁方法(第一种方式)
		通过@Bean指定init-method和destory-method= " "(在xml文件的bean中加入这个两个初始化和销毁方法,并且必须没有参数,而且可以抛任何异常,以前的方式)

在这里插入图片描述
通过类来创建指定的初始化方法和销毁方法(一般在配置数据源初始化的是还要做很多事情,以及销毁的时候也需要做一些列的操作就可以使用这个方式来配置)
在这里插入图片描述
把这个Car类注册到IOC容器中变成一个Spring的Bean组件
在这里插入图片描述
测试:通过创建一个AnnotationConfigApplicationContext对象(也就是第一步,创建一个IOC容器),把MainConfigOfLifeCycle这个类放进去查看这Bean组件
在这里插入图片描述
通过注解@Bean把我们指定的Car类里面的initdetory方法通过initMethod="init",destoryMethod="detory"来匹配,这两个创建和销毁的方法必须是对应Car里面的方法对应的名字
在这里插入图片描述
在启动容器测试:
在这里插入图片描述
在多实例的情况下,Bean是不进行销毁的:
在获取的时候才创建对象:applicationContext.getBean("car")调用这方法的时候才能创建对象,也不会销毁
在这里插入图片描述
在这里插入图片描述

生命周期 InitializingBean和DisposableBean

2)、第二种方式:通过让Bean实现
	Spring提供了其中一个接口`InitializingBean`接口(初始化逻辑),里面的方法表示属性设置完成以后调用,也就相当于初始化方法
	Spring提供了其中一个接口`DisposableBean`接口(定义销毁逻辑)

定义一个类并实现InitializingBeanDisposableBean这两个接口和里面的方法,也就是初始化和销毁的方法,
在这里插入图片描述
并通过@Component注解注册到IOC容器中
在这里插入图片描述
通过扫描的方式把组件扫描到并注册到IOC容器
在这里插入图片描述
测试:
在这里插入图片描述

生命周期 @PostConStruct 和@PreDestory

3)、第三种方式:可以使用JSR250标准

@PostConstruct注解:等这些Bean都装配完成以后来执行一些初始化的方法(对象创建,属性赋值等)来执行标注的这个注解进行初始化
在这里插入图片描述
@PreDestory注解:在这些bean在被移除之前,回调和通知,也就是一出之前给我们一个通知,也就是容器在销毁之前会进行调用通知我们执行销毁工作
在这里插入图片描述
先定义一个类并通过@Compnent注解表示这个类
在这里插入图片描述在这里插入图片描述
测试:
在这里插入图片描述

生命周期 BeanPostProcessor-后置处理器

后置处理器的作用:在Bean初始化前后进行处理工作,打开这个BeanPostProcessor,他是一个接口,他有两个方法,一个是Object postProcessBeforeInitialization(Object bean,String beanName):表示在初始化之前进行后处理工作;还有个方法Object postProcessAfterInitialization(Object bean , String beanName):表示进行初始化之后进行一些后置处理
其中这里的两个参数第一个参数:bean是表示容器帮我们创建的实例,还没有初始化和初始化后;beanName就表示在容器中的名字
在这里插入图片描述
首先自定义一个MyBeanPostProcessor类实现BeanPostProcessor这个接口,表示这个类在初始化前后进行处理,并实现里面的两个方法,并标注@Component注解让它工作:
在这里插入图片描述
其中这两个方法的返回值可以是返回我们要用的bean实例,也可以是返回他原来的对象或者把传进来的对象进行包装之后返回,这里直接返回bean
测试:
在这里插入图片描述
在这里插入图片描述

生命周期 BeanPostProcessor原理

遍历的倒容器中所有的BeanPostProcessor;挨个执行beforeInitialization
一旦返回null,跳出ofr循环,不会执行后面的BeanPostProcessor.PostProcessorsBeforeInitialization
在这里插入图片描述
BeanPostProcessor原理:

populateBean(beanName,mbd,instanceWrapper);//给bean进行属性赋值
initializationBean{
	applyBeanPostProcessorBeaforeInitialzation(warpperBean,beanName);初始化前处理
	invokeInitMethods(beanName,warppedBean,mbd);执行自定义初始化
	appliyBeanPostProcessorAfterInitialization(warppedBean,beanName); //初始化后处理
}	

生命周期-BeanPostProcessor在Spring底层的应用

Spring底层对BeanPostProcessor的使用:
bean的赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxx都是用这个BeanPostProcessor来完成的

自动装配-@Autowried

自动装配:
Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值
1)、@Autowired:自动注入:
①、默认优先按照类型去容器中找对应的组件,applicationConext.getBean(BookDao.class)
②、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找:applicatyionContext.getBean("bookDao")
如何改成第二个呢?
修改我们选择注入的属性名就可以修改成功我们要注入的bookDao2
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
③、@Qualifer(“bookDao”):使用@Qualifer指定需要装配的组件的id而不是使用属性名
在这里插入图片描述
④、只要是标注了自动装配,默认一定要将属性赋值好否则就会报错noSuchAutowriedClass
可以使用@Autowired(required=false)来表示告诉Spring容器能装上的就装,装不上的就不装
在这里插入图片描述
⑤、@Primary:让Spring进行自动装配的时候,默认是用首选的Bean,也就是标注这个注解的组件告诉Spring容器存在多个,并让Spring容器在自动装配的时候首选来装配用了@Primary注解的这个组件,(和属性名没有关系)
在这里插入图片描述
也可以继续使用@Qualifer指定需要装配的bean的名字
在这里插入图片描述

自动装配-@Resource(JSR250)和@Inject(JSR303)【java规范的注解】

@Resource:Java规范,可以和@Autowired一样,实现自动装配功能,默认是按照组件名称进行和装配的
没有支持@Primary功能没有支持@Autowired(reqiured=flase);
在这里插入图片描述
在这里插入图片描述
按照@Resource(name=“bookDao2”)按照名字来装配
在这里插入图片描述
@Inject:
需要导入javax.inject的包和Autowired的功能一样,没有required=flase的功能
在这里插入图片描述
@Autowired:Spring定义的;@Resource、@Inject都是Java规范

AutowiredAnotationBeanProcessor:解析完成自动装配功能

自动装配方法、构造器位置的自动装配

3)、@Autowired:构造器、参数、方法、属性等使用的方式;
都是从容器中获取组件的值

①、标注在方法的位置上

@Bean+方法参数;参数从容器中获取参数组件的值,默认不写@Autowired效果是一样的
在这里插入图片描述
在这里插入图片描述

②、标在构造器上:

(如果组件中只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取)
添加注解@ Component在Class类上,默认加在IOC容器中的组件,容器启动会调用无参构造器创建对象,在进行初始化赋值等操作,这里没写有参的构造器,所以使用boss默认的无参构造器
在这里插入图片描述
Boss类中有参构造器注入,构造器要用的组件,都是从容器中获取
在这里插入图片描述
调用了Boss类中的有参构造器创建对象,而且有参构造器中的Car跟容器中的Car也一样
在这里插入图片描述
在这里插入图片描述

③、放在参数位置

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

【标注在方法位置】:@Bean+方法参数;参数从容器中获取参数组件的值,默认不写@Autowired效果是一样的
在这里插入图片描述
在另外的配置类里面注册Color组件到IOC容器中
在这里插入图片描述
下面测试boss里面的Car和Color里面的Car内存地址是否相同?
在这里插入图片描述

自动装配原理-Aware注入Spring底层组件&原理

4)、自定义组件想要使用Spring容器底层的一些组件(ApplicationConext,BeanFactory ,xxx);自定义组件实现Aware;在创建对象的时候,会调用接口规定的方法注入相关的组件;Aware;
把Spring底层一些组件注入到自定义的Bean中;
xxxAware:功能使用xxxProcessor;每一个xxxAware都有它对应的xxxProcessore
ApplicationContextAware ==》 ApplicationContextAwareProcessor
Aware下的子类全部接口
在这里插入图片描述
编写一个类来继承一些接口并实现里面的方法
private ApplicationContext applicationContext;表示保存的IOC容器到这里方便拿来使用,也就是IOC容器
在这里插入图片描述在这里插入图片描述
测试结果:
在这里插入图片描述
Spring是怎么给Red类中把application注入进来的?
IOC(applicationContext)已经传过来到这个实现的方法里面,里面的这个参数就是application,包含了很多东西
在这里插入图片描述
进入到ApplicationContextAwareProcessor类里面调用了这个方法postProcessorBeforeInitialization里面的一个final Object bean 就是我们定义的Red类,里面包含了这个容器的application,也就是这个Bean就是我们定义的Red类
在这里插入图片描述
通过判断是实现了那个接口
在这里插入图片描述
通过逻辑判断执行invokeAwareInterfaces(bean),把我们写的Red类穿进去做逻辑操作
在这里插入图片描述
这个bean就是Red对象,然后判断这个对象是哪个接口下面的,如果是就判断是那一个Aware,是的话就通过setXXX来注入
在这里插入图片描述
这里我们实现的是这个接口,接下来就把我们这个bean转成ApplciationContextAware并调用setApplication这个方法把这个(this.applicationContext)搞进去
在这里插入图片描述
调用setApplicationContext把IOC传入进来,那么这个bean在初始化的时候利用后置处理器判断这个Bean是ApplicationContextAware,调用Red里面实现接口的setApplicationContext方法把组件传入过来。
在这里插入图片描述
这就是Aware原理,Spring底层组件的注入以及原理

自动装配-@Profile环境搭建

Profile:
Spring为我们提供的可以根据当前环境,动态激活和切换一系列组件的功能
开发环境、测试环境、生产环境
数据源:开发环境中数据源连向A数据库的,测试环境中用测试环境的时候在不改动源代码的情况下数据源连向B数据库,最后项目上线连向C数据库 (/A)(/B)(/C)
数据源添加注册在这里插入图片描述
配置文件数据源:
在这里插入图片描述
通过注解@PropertySource("classpath:/dbconfig.properties")导入进去
在这里插入图片描述
实现EmbeddedValueResovlerAware接口,并把值解析器注册过来private StringValueRosolver,用这个解析到值,实现接口的方法并通过这个setEmbeddedValueResolver接口获取配置文件里的Driver驱动
在这里插入图片描述
把属性注入到类上
在这里插入图片描述
动态设置我们配置的类里的数据源
(测试环境数据源)
在这里插入图片描述
开发数据源
在这里插入图片描述
生产环境的数据源
在这里插入图片描述
测试数据源:
在这里插入图片描述在这里插入图片描述

自动装配-@Profile根据环境注册bean

@Profile:指定组件在那个环境的情况下才能被注册到容器中,不指定,任何环境都能注册这个组件
1)、加了环境表示的bean,只有这个环境被激活的时候才能注册到容器中,默认是default环境
在这里插入图片描述在这里插入图片描述
注册一个bean并标注@Profile("test")注解,这样测试环境的所有bean都会被激活注册进来
在这里插入图片描述
使用命令行动态参数的方式运行:在虚拟机参数位置加载 -Dspring.profile.active=test/dev/pro
在这里插入图片描述
在这里插入图片描述
修改dev开发环境
在这里插入图片描述在这里插入图片描述

2.使用代码的方式激活环境

相当于使用这个有参构造器,在这里插入图片描述
下面我们自己手动配置了

1)、创建一个applicationContext
2)、设置需要激活的环境(可以设置激活多个)
applicationContext.getEnvironment().setActiveProfile("test","dev")
3)、注册主配置类
applicationContext.register(MainConfigProfile.class);
4)、启动刷新容器
applicationContext.refresh();
测试
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值