前言
Spring所依赖的两个核心理念,一个是控制反转(IoC),另一个是面向切面编程(AOP),IoC是Spring的核心。
IoC是一种通过描述来生成或者获取对象的技术,在Spring中把每一个需要管理的对象成为Spring Bean,管理这些Bean的容器,被我们称为Spring IoC容器,IoC容器需要具备以下两个特点:
- 通过描述管理Bean,包括发布和获取。
通过描述完成Bean之间的依赖关系。
IoC容器简介
Spring IoC容器是一个管理Bean的容器,在Spring的定义中,所有的IoC容器都必须实现接口 BeanFactory,它是一个顶级的容器接口。
在 BeanFactory 接口中定义了多个 getBean 方法,它们的意义就是在容器中获取Bean,其中允许我们按照类型或是名称来获取指定的Bean。
默认情况下,Bean在容器中都是以单例存在的。
由于 BeanFactory 接口还不够强大,于是Spring开发了一个更高级的接口 ApplicationContext,它是 BeanFactory 的子接口之一,它在 BeanFactory 的基础上扩展了消息国际化接口(MessageSource)、环境可配置接口(EnvironmentCapable)、应用事件发布接口(ApplicationEventPublisher)和资源模式解析接口(ResourcePatternResolver), 所以它的功能更加强大。
Spring为我们实现了许多IoC容器,这里主要介绍基于注解的容器 AnnotationConfigApplicationContext
依赖注入
Bean之间的依赖关系,Spring的容器概念中,称之为依赖注入。
Bean的生命周期
Bean的生命周期大致上分为,Bean的定义,Bean的初始化,Bean的生存期和Bean的销毁。
Bean的定义的流程如下:
Bean的之后三个流程的流程如下:
注解解析
@Configuration 代表被注解标记的类是一个Java的配置文件。
@Bean 代表被注解标记的方法返回的POJO装配到容器中。
- name 定义容器中Bean的名称,如果没有配置,默认使用方法名作为Bean的名称。
- initMethod 自定义初始化方法
- destroyMethod 自定义销毁方法
@Component 代表被注解标记的类被装配到容器中
- value 定义容器中Bean的名称,如果没有配置,默认使用类名首字母小写作为Bean的名称。
@ComponentScan 表明采用何种策略去装配Bean,该注解默认的扫描路径为标注注解的类所在包以及其子包
- basePackages 指定需要扫描的包,可以使用正则表达式。
- basePackageClasses 指定需要扫描的类。
- includeFilters 满足过滤条件的Bean才扫描。
- excludeFilters 排除过滤条件的Bean才扫描。
lazyInit 延迟初始化,默认为false
@ComponentScan(basePackages = "com.springboot.xx.*", excludeFilters = {@Filter(classes = {UserService.class})}) // 该示例中,指定扫描com.springboot.xx下面的所有包,而排除了UserService的装配,即时该类标注了创建Bean的注解,Spring也不会将其装配到容器中。
@SpringBootApplication 注解中也添加了@ComponentScan注解,我们可以使用它提供的 scanBasePackages scanBasePackageClasses 来配置扫描路径,其外,它还提供了 exclude excludeName 来通过名称或类型来排除自动配置类,如果这些属性满足不了你对装配的需求,可以额外使用@ComponentScan注解。
@Autowired 依赖注入注解,会根据类型找到对应的Bean进行注入,如果寻找的Bean不是唯一的,那么它会根据其属性名称和Bean的名称进行匹配,如果匹配成功,则使用该Bean,如果仍无法匹配,则抛出异常。该注解是一个默认必须找到对应Bean的注解。
- required 如果不能确定注解标注属性一定存在并且允许这个属性为null的时候,可以将该值配置为 false
@Primary 装配优先权注解,当@Autowired找到两个相同类型的Bean时,会优先使用被@Primary标注的Bean,而不是抛出异常。
注意:当多个相同类型的Bean同时标注了@Primary,@Autowired仍会抛出异常。
@Qualifier 与@Autowired一同使用
- value 指定注入的Bean的名称
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。