关于spring:Spring-IoC

67次阅读

共计 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 的名称

正文完
 0