DI和IOC、BeanFactory 和 ApplicationContext区别、Spring设计容器、依赖注入方式、bean的生命、@Autowired、Spring注解的介绍

1介绍一下Spring依赖注入和控制翻转

IOC:它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理;Spring 中的 IoC 的实现原理就是工厂模式加反射机制

2BeanFactory 和 ApplicationContext有什么区别?

在这里插入图片描述

BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。 ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:(MessageSource)支持国际化等;

BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。

BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader。

3Spring 如何设计容器的,BeanFactory和ApplicationContext的关系详解?

Spring 作者 Rod Johnson 设计了两个接口用以表示容器:1BeanFactory 2ApplicationContext
BeanFactory 就是个 HashMap,Key 是 BeanName,Value 是 Bean 实例。通常只提供注册(put),获取(get)这两个功能。我们可以称之为 “低级容器”。ApplicationContext 可以称之为 “高级容器”。他继承了多个接口,因此具备了更多的功能。例如资源的获取,支持多种消息(例如 JSP tag 的支持), “应用上下文”, 代表着整个大容器的所有功能。该接口定义了一个 refresh 方法,用于刷新整个容器,即重新加载/刷新所有的 bean
BeanFactory和ApplicationContext的关系:
在这里插入图片描述
ApplicationContext “高级容器”,依赖着 “低级容器”,这里说的是依赖,不是继承哦。他依赖着 “低级容器” 的 getBean 功能。而高级容器有更多的功能:支持不同的信息源头,可以访问文件资源,支持应用事件(Observer 模式)。IoC 在 Spring 里,只需要低级容器就可以实现,2 个步骤:
1 加载配置文件,解析成 BeanDefinition 放在 Map 里
2 调用 getBean 的时候,从 BeanDefinition 所属的 Map 里,拿出 Class 对象进行实例化,同时,如果有依赖关系,将递归调用 getBean 方法 —— 完成依赖注入
至于高级容器 ApplicationContext,他包含了低级容器的功能,当他执行 refresh 模板方法的时候,将刷新整个容器的 Bean同时其作为高级容器,包含了太多的功能

4有哪些不同类型的依赖注入实现方式?

依赖注入是时下最流行的IoC实现方式,依赖注入分为接口注入(Interface Injection),**Setter方法注入(Setter Injection)和构造器注入(Constructor Injection)**三种方式。其中接口注入由于在灵活性和易用性比较差,现在从Spring4开始已被废弃。
在这里插入图片描述最好的解决方案是用构造器参数实现强制依赖,setter方法实现可选依赖。

5解释Spring框架中bean的生命周期?

在这里插入图片描述
1 Spring对bean进行实例化
2 Spring将值和bean的引用注入到bean对应的属性中;(属性的注入)
3 如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBean-Name()方法;
4 如果bean实现了BeanFactoryAware**接口,**Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入;
5 如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来;

如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessBeforeInitialization()方法;

如果bean实现了InitializingBean接口,Spring将调用它们的after-PropertiesSet()方法。类似地,如果bean使用initmethod声明了初始化方法,该方法也会被调用;

如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessAfterInitialization()方法;

此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁

如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。

现在你已经了解了如何创建和加载一个Spring容器。但是一个空的容器并没有太大的价值,在你把东西放进去之前,它里面什么都没有。为了从Spring的DI(依赖注入)中受益,我们必须将应用对象装配进Spring容器中。

6使用@Autowired注解自动装配的过程是怎样的?

使用@Autowired注解来自动装配指定的bean。在使用 @Autowired注解之前需要在Spring配置文件进行配置,<context:annotation-config />。

启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性。在使用@Autowired时,首先在容器中查询对应类型的bean:

如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据;
如果查询的结果不止一个,那么@Autowired会根据名称来查找
如果上述查找的结果为空,那么会抛出异常。解决方法时,使用required=false。

7Spring注解的介绍?

@Configuration 注解为例,它用来标记类可以当做一个bean的定义,被Spring IOC容器使用。@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文

1@Component, @Controller, @Repository, @Service 有何区别?

@Component:这将 java 类标记为 bean它是任何 Spring 管理组件的通用构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。

@Controller:这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IoC 容器中。

@Service:此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。您可以在服务层类中使用 @Service 而不是 @Component,因为它以更好的方式指定了意图

@Repository:这个注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了额外的好处。它将 DAO 导入 IoC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。

2@Required 注解有什么作用?

这个注解表明bean的属性必须在配置的时候设置,@Required注解的bean属性未被设置,容器将抛出BeanInitializationException。

3@Autowired 注解有什么作用?

@Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。

4@Autowired和@Resource之间的区别?

@Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。
@Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。

5@Qualifier 注解有什么作用?

当您创建多个相同类型的 bean希望仅使用属性装配其中一个 bean 时,您可以使用**@Qualifier 注解和 @Autowired 通过指定应该装配哪个确切的 bean 来消除歧义**。

猜你喜欢

转载自blog.csdn.net/zs18753479279/article/details/115275327