Spring IoC&DI

文章目录

IoC容器

  1. 容器:内部装的是对象

  2. IoC:Inversion of Control,控制反转(获得依赖对象的过程反转了)。如果A需要对象B,那么A就会主动实例化B类,控制权在A手中。反转就是将控制权交给一个第三方角色(IoC容器),由他来创建B,A只需要等待对象传递给他。

    比如说:初创公司是由老板统一管理所有员工,当公司发展壮大,老板就将员工的管理交给HR。老板不用关心员工的情况,只需要安排工作就好

优点:

  1. 资源集中管理
  2. 降低耦合度

IoC举例

创建一个车对象:

在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire

需要在Car类中实例化Framework对象,在Framework类中实例化Bottom对象

改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car

Car不需要实例化Framework类,只需要实例化Car类时将Framework对象传入。同样Framework也不需要实例化Bottom对象,在实例化将Framework类时将Bottom传入就好.

这就实现了车与 车身的解耦,车身与底盘的解耦...

将依赖关系反转了

DI

IoC控制反转是一种思想,而DI就是IoC的一种实现方式。也就是通过DI来实现IoC

Dependency Injection依赖注入:容器运行期间动态的为应用程序提供运行时所依赖的资源

依赖:类A的方法里需要调用类B的方法,就是类A依赖于类B

注入:将类B的实例提供给类A的过程

java 复制代码
Tire tire=new Tire(13);
Bottom bottom=new Bottom(tire);
Framework framework=new Framework(bottom);
car c=new car(framework);
// IoC容器内就存储着这些对象

Spring IoC

Spring就是包含了众多方法的IoC容器,由Spring掌握对象的控制权

Bean

所有由Spring IoC容器负责创建、组装和管理的对象统称为Bean

  1. 类注解:@Controller(控制器存储)、@Service(服务器存储)、@Repository(仓库存储)、@Configuration(配置存储)、@Component(组件存储)
  2. 方法注解:@Bean

类注解的使用

Bean的存储

每个类注解的使用方法类似,这里以@Component举例

将类加上@Component注解,表示这个类的实现由Spring控制

java 复制代码
@Component
public class UserController {
    public void sayHi(){
        System.out.println("Hi");
    }
}
Bean的获取

从Spring上下文中获取对象

上下文:就是指当前的运行环境,也可以看作一个容器,容器内存放着当前的运行环境

  1. 获取上下文

    java 复制代码
    ApplicationContext context=SpringApplication.run(IocApplication.class, args);
  2. 通过getBean()获取对象

    java 复制代码
    //通过类型,适用于只实例化一个对象
    UserController userController1= context.getBean(UserController.class);
    //通过Bean名,需要强转
    UserController userController2= (UserController)context.getBean("userController");
    //通过Bean名和类型
    UserController userController3 = context.getBean("userController",UserController.class);

    Bean名的约定 :类名的小驼峰格式

    特殊情况:前两个字母为大写,Bean名则为原类名

    类名: AManager, Bean的名称为: AManager

    也可以通过注解指定名称 @Controller(name)

ApplicationContext获取Bean()对象的方法,是继承自父类BeanFactory

  • 继承关系和功能:Spring容器的两个顶级接口BeanFactory和ApplicationContext,BeanFactory提供了基础访问容器的能力 ,ApplicationContext是BeanFactory的子类,除继承了BeanFactory所有的方法 以外,还拥有额外的特性。如国际化支持、资源的访问、事件传播
  • 性能:ApplicationContext是一次性加载并初始化所有Bean ,BeanFactory是需要哪个才去加载哪个
为什么有这么多类注解
联系

@Controller@Service@Repository@Configuration这三个注解都是@Component的子注解,也称为衍生注解

与应用分层相呼应,程序员看到类注解之后,就能知道这个类的具体用途

  1. @Controller:控制层,接收请求,对请求进行处理并进行相应
  2. @Service:业务逻辑层,处理具体的业务逻辑
  3. @Repository:数据访问层,也称为持久层,负责数据的访问操作
  4. @Configuration:配置层,处理项目中的配置信息
  5. @Component:组件层
区别

@Controller不能和其他注解替换,控制层必须使用@Controller。其他注解可以相互替换(但是不建议,因为不同注解表示的含义不同)

方法注解@Bean

使用场景

  1. 一个类需要多个对象
  2. 一个类的实例化过程非常复杂,将这些复杂的逻放到@Bean方法里会非常清晰
  3. 有些外部类,不能添加类注解,但是还需要Spring去管理这个类
java 复制代码
public class Student {
   public String name;
   public  int age;
    @Bean({"s1","student1"})
    public Student s1(){
        return new Student("张三",11);
    }
    @Bean
    public String name2(){
        return "张三";
    }
    @Bean({"s2","student2"})
    public Student s2(String name){
        return new Student(name,13);
    }
}

当Spring启动时,发现s1(),s2()方法上有@Bean注解。Spring会主动调用这个方法,拿到返回的Student对象

  1. @Bean的名称默认为方法名,也可在注解上进行指定(可指定多个名称)
  2. @Bean注解的方法需要接收参数时,Spring会从Spring容器中查找对应类型的对象(必须是唯一的),赋值到参数中
  3. 获取Bean使用context.getBean("BeanName");方法

扫描路径

默认扫描路径

启动类同级的目录及其子目录

修改扫描路径

使用@ComponentScan注解可以修改扫描路径,修改后以@ComponentScan规定的路径为主

java 复制代码
@ComponentScan("包名") //会扫描指定包名下所有的文件,放在启动类上方

Spring DI

依赖注入:简单来说就是将对象取出来放到某个类的属性中

  1. 属性注入(Field Injection)
  2. 构造方法输入(Construction Injection)
  3. Setter注入(Setter Injection)

使用@Autowired注解

原理 :在Spring创建Bean的属性填充阶段,会利用反射扫描全类,找到@Autowired标记的位置,然后遵循"先类型后变量名"的原则。从容器内找到合适的依赖对象,最后通过反射将其注入到代码中

缺陷 :如果一个类存在多个对象,且@Autowired标记的字段不是Bean名就会报错

解决办法

  1. @Primary:指定对应的默认对象

  2. @Qualifier:在@Autowired上方加上@Qualifier(BeanName)注解用于指定Bean名称。也可加在参数上

    java 复制代码
    @Bean
    public Student s2(@Qualifier("Name1") String name){
    return new Student(name,13);
    }
    @Qualifier("s1")
    @Autowired
    Student s11;
  3. @Resource:使用@Resource(BeanName)代替@Autowired

    @Resource(BeanName)@Autowired区别:

    • @Autowired是spring框架提供的注解,而@Resource是JDK提供的注解
    • @Autowired默认是按照类型 注入,而@Resource是按照名称注入

属性注入

java 复制代码
@Autowired
UserService userService;

优点

  1. 简洁,使用方便

缺点

  1. 只能作用于IoC容器
  2. 不能注入一个Final修饰的属性,因为Final修饰的属性在编译时要有确切的值

构造函数注入

  1. 如果类只有一个构造函数,默认使用唯一的构造函数
  2. 如果类中有多个构造函数,默认使用无参的构造函数
  3. 使用@Autowired注解可以指定使用的构造函数
java 复制代码
final UserService userService;
UserConfig userConfig;
@Autowired
public HelloController(UserService userService, UserConfig userConfig) {
   this.userService = userService;
   this.userConfig = userConfig;
}

优点

  1. 可以注入final修饰的属性
  2. 注入的对象不会被修改
  3. 依赖对象在使用前一定会被完全初始化,因为依赖注入是在构造函数中进行的,而构造函数是在类加载阶段执行的
  4. 通用性好,构造方法是JDK 支持的,更换任何框架都适用

缺点

  1. 注入多个对象时,代码较为繁琐

Setter注入

Setter注入和属性的Setter方法实现类似,设置set方法时需要加上@Auto wired注解

java 复制代码
UserService userService;
UserConfig userConfig;
@Autowired
public void setUserConfig(UserConfig userConfig) {this.userConfig = userConfig;}
@Autowired
public void setUserService(UserService userService) {this.userService = userService;}

优点

  1. 方便在类实例之后,重新对该对象进行配置或注入

缺点

  1. 不能注入一个final修饰的属性
  2. 注入的对象可能会被改变,因为Setter方法可能会被多次调用

总结

SpringMVC和Spring Boot都属于Spring,Spring MVC是基于Spring的一个MVC框架,而Spring Boot是基于Spring的一套快速开发整合包

Spring

Spring: 简单来说, Spring 是一个开发应用框架 ,什么样的框架呢,有这么几个标签:轻量级、一 站式、模块化,其目的是用于简化企业级应用程序开发.

Spring的主要功能: 管理对象 ,以及对象之间的依赖关系 , 面向切面编程 , 数据库事务管理 , 数据访问 , web框架支持等. 但是Spring具备高度可开放性, 并不强制依赖Spring, 开发者可以自由选择Spring的部分或者全部, Spring可以无缝继承第三方框架, 比如数据访问框架(Hibernate 、JPA), web框架(如Struts、 JSF)

Spring MVC

Spring MVC是Spring的一个子框架 , Spring诞生之后, 大家觉得很好用, 于是按照MVC 模式设计了一个 MVC框架(一些用Spring 解耦的组件), 主要用于开发WEB应用和网络接口 ,所以, Spring MVC 是一个Web框架.

Spring Boot

Spring Boot是对Spring的一个封装 , 为了简化Spring应用的开发而出现的,中小型企业,没有成本研究自己的框架, 使用Spring Boot可以更加快速的搭建框架, 降级开发成本, 让开发人员更加专注于Spring应用的开发,而无需过多关注XML的配置和一些底层的实现

比如想使用SpringBoot开发Web项目 , 只需要引入Spring MVC框架 即可, 想完成数据访问, 只需要引入Mybatis框架即可.

EB应用和网络接口**,所以, Spring MVC 是一个Web框架.

Spring Boot

Spring Boot是对Spring的一个封装 , 为了简化Spring应用的开发而出现的,中小型企业,没有成本研究自己的框架, 使用Spring Boot可以更加快速的搭建框架, 降级开发成本, 让开发人员更加专注于Spring应用的开发,而无需过多关注XML的配置和一些底层的实现

比如想使用SpringBoot开发Web项目 , 只需要引入Spring MVC框架 即可, 想完成数据访问, 只需要引入Mybatis框架即可.

相关推荐
十六年开源服务商2 小时前
游戏与设计驱动WordPress建站2026
java·前端·游戏
尚雷55802 小时前
从电商订单支付更新,吃透 Oracle 数据修改的底层设计哲学与全组件协同原理
数据库·oracle
前进吧-程序员2 小时前
C++ 内存到底分配在哪?
java·jvm·c++
NWU_白杨2 小时前
VoiceMockInterview项目MVP开发
java·ai
2401_832365522 小时前
Chart.js 4 中基于数据实际范围的线性渐变填充方案
jvm·数据库·python
RDCJM2 小时前
Springboot的jak安装与配置教程
java·spring boot·后端
qq_342295822 小时前
如何让 Bootstrap 图标在 Vue 3 中持续旋转动画
jvm·数据库·python
呱牛do it2 小时前
企业级门户网站设计与实现:基于SpringBoot + Vue3的全栈解决方案(Day 4)
java·vue
李兆龙的博客2 小时前
从一到无穷大 #70 从 LR 图 PEC 到InfluxQL兼容性差分测试方法论与工程实践
数据库·功能测试·oracle