文章目录

  • 一、前言
  • 二、IOC
  • 1.特点:
  • 目的
  • 三、stereotype annotations 模式注解
  • 1. @Component
  • 2. @Service,@Controller,@Repository
  • 3. @Configuration
  • 4. 1,2和3的区别
  • 四、spring实例化和依赖注入时机与延迟加载
  • 1. 注入时机
  • 2. 延迟实例化(重点)
  • 五、注入方式
  • 1. Autowired注入
  • 2. 构造器注入(推荐)
  • 3. Set注入
  • 六、@Autowired注入详解
  • 1. bytype和byname
  • 2. @Qualifier主动注入
  • 七、应对变化的两种解决方案
  • 1. 策略模式
  • 2. 属性配置
  • 八、@Configuration详解
  • 1. 表面意义上的作用
  • 2. 用来代替bean的xml配置
  • 为什么要把变化放在配置文件中
  • 3.@Configuration和@Bean 实际意义上的作用
  • 1. 配置分类
  • 2. 把变化放到配置文件中


一、前言

在我们项目中,肯定是springFramework和SpringBoot用的最多,比如我们也都了解了,@Component把类加入到容器,使用的时候用@Autowired就可以了。大多数人可能只了解到这个程度,因为到这个程度基本上就能够使用了,项目中基本上也是这个最多。但是在面试中或者一些场景却远远不够,这篇文章会更加深入的讲解底层的一些东西,相信对大家学习和面试都会有很大的帮助。

二、IOC

1.特点:

主要特点是有个容器,把对象加入到容器中,在需要的时候可以注入到代码中

目的

抽象意义:控制权交给用户

三、stereotype annotations 模式注解

1. @Component

把对象加入到容器中

2. @Service,@Controller,@Repository

和@Component基本一样,只是为了区分在哪层。

3. @Configuration

相当于可以把多个类加入到容器中。

从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

4. 1,2和3的区别

  1. @Configuration可以可以把多个类加入到容器中,那几个注解不行
  2. 如果使用 @Configuration 注解修饰的类,并且该注解中的 proxyBeanMethods 属性的值为 true,则会为这个 bean 创建一个代理类,该代理类会拦截所有被 @Bean 修饰的方法,在拦截的方法逻辑中,会从容器中返回所需要的单例对象。
  3. 如果将 @Configuration 注解中的 proxyBeanMethods 属性的值设置为 false,那么它的行为是否就会跟 @Component 注解一样。
  4. 如果使用 @Component等 注解修饰的类,则不会为这个 bean 创建一个代理类。 那么我们就会直接执行用户的方法,所以每次都会返回一个新的对象。

四、spring实例化和依赖注入时机与延迟加载

1. 注入时机

应用启动的时候实例化的注入,但可以更改变成延迟实例化。

2. 延迟实例化(重点)

类上加上@Lazy注解,但是可能还是会立即实例化。
比如我们在dao层加上@Repository和@Lazy,在Service层调用了,但是Service层没有打上@Lazy注解,这样dao层会立即实例化,不会延迟加载,因为不可能@Service立即实例化,而里面注入的dao没有实例化。

五、注入方式

1. Autowired注入

这种方式最不推荐,但我们基本都这么用。为什么不推荐?

  1. 下面会空指针错误
@Autowired
private UserService userService;

private String company;

public UserServiceImpl() {
    this.company = userService.getCompany();
}

原因:

Java 在初始化一个类时,是按照静态变量或静态语句块 –> 实例变量或初始化语句块 –> 构造方法 -> @Autowired 的顺序。所以在执行这个类的构造方法时,user对象尚未被注入,它的值还是 null。

  1. 依赖注入的核心思想之一就是被容器管理的类不应该依赖被容器管理的依赖,换成白话来说就是如果这个类使用了依赖注入的类,那么这个类摆脱了这几个依赖必须也能正常运行。然而使用变量注入的方式是不能保证这点的。

2. 构造器注入(推荐)

spring boot 构造函数泛型注入 springboot构造器注入注解_依赖注入

3. Set注入

spring boot 构造函数泛型注入 springboot构造器注入注解_依赖注入_02

六、@Autowired注入详解

1. bytype和byname

默认是按照bytype注入,如果一个接口有多个实现类,则按照name注入。
总结:

  1. 找不到任何一个bean 报错
  2. 找到唯一一个bean 直接注入
  3. 找到多个 不一定报错 按照name匹配

2. @Qualifier主动注入

可以按照名字注入

七、应对变化的两种解决方案

1. 策略模式

制定一个interface,多个类实现同一个interface

2. 属性配置

通过配置文件来解决变化

八、@Configuration详解

1. 表面意义上的作用

类中分为行为和特征,如何类中有属性,如何给属性赋值呢?@Component不能给类中属性赋值。

但是@Configuration可以给属性赋值,因为是我们自己实例化的。

spring boot 构造函数泛型注入 springboot构造器注入注解_依赖注入_03

2. 用来代替bean的xml配置

spring boot 构造函数泛型注入 springboot构造器注入注解_依赖注入_04

为什么要把变化放在配置文件中

  1. 配置文件具有集中性
  2. 清晰(没有清晰性)

3.@Configuration和@Bean 实际意义上的作用

1. 配置分类

  1. 常规配置 key:value
  2. xml配置

2. 把变化放到配置文件中

spring boot 构造函数泛型注入 springboot构造器注入注解_实例化_05

MySQL的业务非常复杂,涉及到的可能不止一个类,这个时候就可以用配置类,把所有相关的类注入到配置类中,变化的都在配置类中。