共计 2764 个字符,预计需要花费 7 分钟才能阅读完成。
前言
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 的定义的流程如下:
graph TD
R1[例如 ComponentScan 注解所定义的扫描包]
R2[将 Bean 的定义保留到 BeanDefinition 的实例中]
R3[IoC 容器装载 Bean 定义]
F1[资源定位]
F2[Bean 定义]
F3[公布 Bean 定义]
R1 -.-> F1
R2 -.-> F2
R3 -.-> F3
F1 --> F2
F2 --> F3
Bean 的之后三个流程的流程如下:
graph TD
R1([接口 BeanNameAware])
R2([接口 BeanFactoryAware])
R3([接口 ApplicationContextAware - 须要容器实现 ApplicationContext 接口才会被调用])
R4([接口 BeanPostProcessor 的预初始化办法 - 针对全副 Bean 失效])
R5([PostConstruct 注解标注的办法])
R6([接口 InitializingBean])
R7([接口 BeanPostProcessor 的后初始化办法 - 针对全副 Bean 失效])
R8([PostConstruct 注解标注的办法])
R9([接口 DisposableBean])
F1[初始化]
F2[依赖注入]
F3[setBeanName 办法]
F4[setBeanFactory 办法]
F5[setAppliationContext 办法]
F6[postProcessBeforeInitialization 办法]
F7[自定义初始化办法]
F8[afterPropertiesSet 办法]
F9[postProcessAfterInitialization 办法]
F10{生存期}
F11[自定义销毁办法]
F12[destory 办法]
F1 --> F2 ---> F3
R1 -.-> F3
F3 ---> F4
R2 -.-> F4 ---> F5
R3 -.-> F5
F5 ---> F6
R4 -.-> F6
F6 ---> F7
R5 -.-> F7
F7 ---> F8
R6 -.-> F8
F8 ---> F9
R7 -.-> F9
F9 ---> F10 --> F11
R8 -.-> F11
F11 ---> F12
R9 -.-> F12
注解解析
@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 的名称