注解操作实现IOC内置Bean的各种操作
Annotation
组件注册导进IOC容器
-
@bean
- @Conditional
按照条件进行装配bean的操作
代码实现
自定义一个类完成自定义条件,自定义类继承
Condition类,实现方法在配置类的装配方法加上注解
@Condition(MyCondition.class) -
@Configuration:注册配置类-(相当于配置文件)
-
包扫描+组件注解()
ComponentScan/@Controller/@Service/@Repository/@Component -
@Import
-
在配置类上加上
@import(导入的组件)能快速导入组件(自动注册),id默认是全类名 -
ImportSelector:返回需要导入的组件全类名数组
通过自定义类继承ImportSelector并实现方法完成自定义导入装配bean
@Import(MyImportSelector.class)即可,ImportSelector内没有返回则会将自身装配进IOC容器 -
ImportBeanDefinitionRegistry:手动注册bean到容器
- Spring提供的FactoryBean
- 默认获取到的是
工厂bean调用的getObject创建的对象 - 获取
工厂bean本身需要在id前面加前缀&
Springboot含有大量自动配置,其实依靠它们
@Configuration,@Import,@Conditional
管理bean生命周期
生命周期:创建 -> 初始化 -> 销毁的过程
Spring允许我们自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候调用我们自定义的初始化和销毁方法
初始化和销毁什么时候执行?
初始化:
对象创建完成并赋值后,调用初始化方法
销毁:
单实例bean在容器关闭时自动销毁
多实例bean,容器不会调用bean的销毁方法
-
指定初始化和销毁
init-method和destroy-method@Bean(initMethod="方法名", destroyMethod="方法名")指定方法
-
通过让Bean实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁逻辑)
- 组件类继承
InitializingBean, DisposableBean,实现其初始化,销毁方法
- 组件类继承
-
使用
JSR250规范(Java的一种规范)@PostConstruct标注在初始化方法上@PostDestroy标注在销毁方法上
-
BeanPostProcessor-bean的后置处理器是对bean初始化前后进行的一些处理
实现BeanPostProcessor接口来自定义后置处理器
postProcessBeforeInitialization方法:在初始化之前工作postProcessAfterInitialization方法:在初始化之后工作
底层原理:
首先在Bean初始化方法
invokeInitMethods(beanName, wrappedBean, mbd)执行初始化前,先执行applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)来for循环其所有BeanPostProcessor,并执行其BeanPostProcessorBeforeInitialization方法,返回null则直接结束循环返回结果,不会执行之后的BeanPostProcessor。同理于applyBeanPostProcessorsAfterInitialization大致流程:
populateBean(beanName, mbd, instanceWrapper);-> 给bean属性赋值- initializeBean
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)invokeInitMethods(beanName, wrappedBean, mbd)->执行初始化applyBeanPostProcessorsAfterInitialization
Spring当中的
BeanPostProcesso实现类有哪些?(挑局部的来讲)AutowiredAnnotationBeanPostProcessor-> 自动注入组件注解的实现,来对bean进行赋值(容器中含有则找到这个singleton bean)initDestroyAnnotationBeanPostProcessor-> 找到控制生命周期的注解方法,利用反射调用MethodValidationPostProcessor-> bean赋值校验@Async等等xxBeanPostProcessor
属性赋值
@Value
- 赋基本数值 ->
@value("基本数值") Spring表达式(SpEL - Spring Expression Language)->#{}- 读取配置文件 -
运行在环境变量中->${}- 可以使用
@PropertySource(value={"路径如:classpath:/xxx.properties"})读取配置文件中的Key-Value保存到运行时环境变量中
- 可以使用
自动装配
Spring使用依赖注入(DI)来对IOC容器中各个组件的依赖关系赋值
Spring支持以下常用注解开发,都是由AutowiredAnnotationBeanPostProcessor解析完成自动装配的功能
-
@Autowired- 默认优先按照类型在容器中寻找对于的组件
- 有多个相同类型的组件,将按照组件名称的id去找
- 可以使用
@Qualifier("")指定需要装配的组件id - 默认要赋值,找不到就会报错(设置
@Autowired(required=false)则可以为null) @Primary给某个bean设置为默认首选装配对象,@Qualifier也生效
可以在构造器,参数,方法,属性上标注@Autowired,凡在参数或方法或构造器,都是将其参数从容器拿
注意:如果组件只有一个有参构造器,这个有参构造器@Autowired可省略,该参数默认从容器中获取
-
@Resource ->(JSR250) [Java规范的注解]和@Inject->(JSR330) [Java规范的注解]@Resource:- 跟@Autowired相同效果,id默认赋值组件名称
- 不支持@Primary,和没有require的属性
@Inject:- 需要导包javax.inject,也没有require属性
-
...等等
-
Aware接口:把Spring底层的组件注入自定义的Bean
在自定义组件想使用Spring容器底层的一些组件如ApplicationContext,BeanFactory,xxx等,可以自定义组件实现xxxAware接口(xxxAware继承自Aware接口),调用接口方法来注入相关组件。
xxxAware的功能也是使用xxxProcessor继承BeanPostProessor来实现的
如
ApplicationContextAware -->ApplicationContextAwareProcessor底层实现流程是
调用
ApplicationContextAwareProcessor的PostProcessorBeforeInitialization方法,该方法内先判断bean是否继承自xxxAware接口,有则判断AccessControlContext是否赋值,有值则进入doPrivileged方法执行权限检查判断是否有权限访问,AccessControlContext为null则调用私有方法invokeAwareInterface(bean)来判断继承自哪一个xxxAware接口并将相应的组件注入进来(本例子是ApplicationContext)简单来说就是:
- 本组件bean在初始化之前调用后置处理器
ApplicationContextAwareProcessor的PostProcessorBeforeInitialization方法- 判断该bean继承自那个
xxxAware组件(本例是ApplicationContextAware)`- 将此
xxxAware对应的Spring容器底层组件调用setxxx方法注入进bean(本例是setApplicationContext(ApplicationContext context))
@Profile
按照环境条件选择注入bean

浙公网安备 33010602011771号