??前言Spring依赖于两个核心概念,一个是控制反转(IoC),一个是面向切面编程(AOP)。IoC是Spring的核心。IoC是一种通过描述来生成或获取对象的技术。在Spring中,每一个需要管理的对象都成为一个SpringBean。管理这些bean的容器称为SpringIoC容器。IoC容器需要具备以下两个特性:通过描述管理Bean,包括发布和获取。bean之间的依赖是通过描述来完成的。IoC容器介绍SpringIoC容器是管理bean的容器。在Spring的定义中,所有的IoC容器都必须实现接口BeanFactory,这是一个顶级的容器接口。BeanFactory接口中定义了多个getBean方法,其含义是获取容器中的bean,可以让我们通过类型或名称获取指定的bean。默认情况下,bean在容器中作为单例存在。由于BeanFactory接口不够强大,Spring开发了一个更高级的接口ApplicationContext,它是BeanFactory的子接口之一,在BeanFactory的基础上扩展了消息国际化接口(MessageSource)和环境可配置接口(EnvironmentCapable),应用事件发布接口(ApplicationEventPublisher)和资源模式解析接口(ResourcePatternResolver),因此其功能更加强大。Spring为我们实现了很多IoC容器。这里主要介绍基于注解的容器Bean依赖之间的AnnotationConfigApplicationContext依赖注入。在Spring的容器概念中,称为依赖注入。Bean的生命周期Bean的生命周期大致分为,Bean定义、Bean初始化、Bean生命周期和Bean销毁。Bean定义的过程如下:图TDR1【例如ComponentScan注解定义的扫描包】R2【将Bean的定义保存到BeanDefinition的实例中】R3【IoC容器加载Bean定义】F1【资源位置】F2[Bean定义]F3[ReleaseBeanDefinition]R1-.->F1R2-.->F2R3-.->F3F1-->F2F2-->F3Bean接下来三个进程的流程如下:graphTDR1([InterfaceBeanNameAware])R2([InterfaceBeanFactoryAware])R3([InterfaceApplicationContextAware-需要容器实现ApplicationContext接口才能调用])R4([InterfaceBeanPostProcessor的预初始化方法-对所有Bean有效])R5([PostConstruct注解方法])R6([InterfaceInitializingBean])R7([InterfaceBeanPostProcessor的后初始化方法-对所有bean有效])R8([PostConstruct注解方法])R9([InterfaceDisposableBean])F1[Initialization]F2[Dependency注入]F3[setBeanName方法]F4[setBeanFactory方法]F5[setAppliationContext方法]F6[postProcessBeforeInitialization方法]F7[自定义初始化方法]F8[afterPropertiesSet方法]F9[postProcessAfterInitialization方法]F10{lifetime}F11[自定义销毁方法]F12[销毁方法]F1-->F2--->F3R1-.->F3F3--->F4R2-.->F4--->F5R3-.->F5F5--->F6R4-.->F6F6--->F7R5-.->F7F7--->F8R6-.->F8F8--->F9R7-.->F9F9--->F10-->F11R8-.->F11R8-.->;F11F11--->F12R9-.->F12注解分析@Configuration表示注解所标注的类是Java配置文件@Bean表示注解所标注的方法返回的POJO被组装到容器中。name定义容器中bean的名称。如果没有配置,默认使用方法名作为bean的名字。initMethod自定义初始化方法destroyMethod自定义销毁方法@Component表示将注解类组装到容器中。值定义容器中bean的名称。如果不配置,默认使用类名首字母的第一个字母作为bean名。@ComponentScan表示使用哪种策略来组装Bean。注解的默认扫描路径是被注解类所在的包,其子包basePackages指定要扫描的包。可以使用正则表达式。basePackageClasses指定需要扫描的类。includeFilters只扫描满足过滤条件的bean。excludeFilters在扫描之前排除过滤条件的Bean。lazyInit延迟初始化,默认为false@ComponentScan(basePackages="com.springboot.xx.*",excludeFilters={@Filter(classes={UserService.class})})//本例中指定扫描com.弹簧靴。xx下的所有package都排除了UserService的组装,即使该class打上了创建bean的注解,Spring也不会组装到容器中。@ComponentScan注解也被添加到@SpringBootApplication注解中。我们可以使用它提供的scanBasePackagesscanBasePackageClasses来配置扫描路径。此外,它还提供了excludeexcludeName来按名称或类型排除自动配置类。如果这些属性不能满足你的组装需求,你可以额外使用@ComponentScan注解。@Autowired依赖注入注解会根据类型找到对应的Bean进行注入。如果您要查找的Bean不是唯一的,那么它将匹配其属性名称和Bean的名称。如果匹配成功,则使用该Bean。如果仍然无法匹配,则抛出异常。这个注解是默认必须找到对应Bean的注解。required如果不确定注解属性必须存在,允许该属性为null,可以配置值为false@Primaryassemblypriority注解。当@Autowired发现两个相同类型的bean时,会优先使用@Primary注解的bean,而不是抛出异常。注意:当多个相同类型的bean同时被@Primary标记时,@Autowired仍然会抛出异常。@Qualifier和@Autowired使用value来指定注入的Bean的名称
