前言

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 TDR1[例如ComponentScan注解所定义的扫描包]R2[将Bean的定义保留到BeanDefinition的实例中]R3[IoC容器装载Bean定义]F1[资源定位]F2[Bean定义]F3[公布Bean定义]R1 -.-> F1R2 -.-> F2R3 -.-> F3F1 --> F2F2 --> F3

Bean的之后三个流程的流程如下:

graph TDR1([接口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 ---> F3R1 -.-> F3F3 ---> F4R2 -.-> F4 ---> F5R3 -.-> F5F5 ---> F6R4 -.-> F6F6 ---> F7R5 -.-> F7F7 ---> F8R6 -.-> F8F8 ---> F9R7 -.-> F9F9 ---> F10 --> F11R8 -.-> F11F11 ---> F12R9 -.-> 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的名称