当前位置: 首页 > news >正文

Spring IOC与DI

spring的两大思想:IOC与AOP

一、ioc的概念

什么叫控制翻转?

之前:

对象的使用方,创建对象,对象的控制权,在对象的使用方手中.

spring:

对象的控制权交给了spring.

举个例子:智能驾驶,之前车的使用权在人手中,而现在在ai手中,这就是控制反转.

什么叫ioc:

之前车企生产车需要做整个车,费事费力无法定制化,而现在车企将轮胎轮毂车底等外包给别人做,自己制作组装:

二、DI

本质上就是想在不new的基础上完成对象引入,目的是解耦.

依赖注入分为三种:

1.属性注入

    @Autowiredprivate  StudentController studentController;public void say(){System.out.println("helloworld");studentController.say();}

@Autowired就是属性注入的注释\

正常来说应该是

这样,但是加了属性注入注释就将这个注入到这个对象中了.

// 1. 定义一个服务类(被依赖的对象)
@Service // 告诉Spring:这是一个服务,需要被容器管理
public class UserService {public void doService() {System.out.println("执行服务逻辑");}
}// 2. 定义控制器(需要依赖的对象)
@Controller // 告诉Spring:这是一个控制器,需要被容器管理
public class UserController {// 3. 声明依赖:告诉Spring,我需要一个UserService对象@Autowired private UserService userService;public void doController() {// 直接使用注入的对象,不用自己newuserService.doService(); }
}

@Autowired会根据名称进行注入,如果服务类中有多个名字对不上的该怎么办呢?有三种方法:

@Autowired与@Resource的区别:

1.注入顺序

  @Autowired:默认按类型(Type)匹配注入。

  • 先根据字段 / 参数的类型在 Spring 容器中查找匹配的 Bean。
  • 如果存在多个同类型的 Bean,需要配合 @Qualifier 注解按名称(Name)筛选,否则会报错。
    示例:
    @Autowired
    @Qualifier("userServiceA") // 指定名称为userServiceA的Bean
    private UserService userService;

    @Resource:默认按名称(Name)匹配注入,名称可以通过 name 属性指定。

  • 若未指定 name,则默认使用字段名或 setter 方法名作为 Bean 名称。
  • 若按名称找不到匹配的 Bean,会 fallback 到按类型匹配。
    示例:
    @Resource(name = "userServiceA") // 直接指定Bean名称
    private UserService userService;// 未指定name时,默认按字段名"userService"查找
    @Resource
    private UserService userService;
2.来源

@Autowired是spring提供的注释,@Resource是JDK提供的注释.

2.构造方法注入

通过构造方法进行注入

package com.example.demo;import org.springframework.stereotype.Controller;// 控制器类(需要依赖的对象)
@Controller
public class UserController {// 依赖的服务对象,使用final修饰确保不可变private final UserService userService;// 构造方法注入:通过构造方法传入依赖// Spring会自动找到匹配的UserService对象注入进来public UserController(UserService userService) {this.userService = userService;}public void showUserName() {// 使用注入的依赖对象System.out.println("用户名:" + userService.getUserName());}
}

总所周知,构造方法可以有无参和有参,这是怎么告诉spring哪个是我们想要的:

@Controller
public class UserController {private final UserService userService;// 无参构造方法(手动定义)public UserController() {// 注意:如果用无参构造创建对象,userService会为nullthis.userService = null;}// 有参构造方法(用于注入依赖)@Autowired // 必须添加,否则Spring会优先用无参构造public UserController(UserService userService) {this.userService = userService;}public void doSomething() {userService.doService(); // 只有通过有参构造创建的对象才能正常调用}
}

3.setter方法注入

package com.example.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {private UserService userService;// setter方法注入:通过setter方法传入依赖@Autowired // 标注在setter方法上public void setUserService(UserService userService) {this.userService = userService;}public void showUserName() {// 使用注入的依赖对象System.out.println("用户名:" + userService.getUserName());}
}

三、bean的存储

将对象交给spring进行管理可以使用下面的这些注释:

类注解:

用代码来讲解:

@Controller
public class UserController {public void say(){System.out.println("hello world");}
}

创建一个UserController类,如果要使用其中的对象就得new UserController(),来实例化对象,而此处我们加上@Controller后就是将对象托管给spring,而我们只需要从Spring中取对象即可,下面讲解一下取对象的具体步骤:

@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {ApplicationContext context=SpringApplication.run(DemoApplication.class, args);//1.通过类型取UserController controller=context.getBean(UserController.class);controller.say();//2.通过名字取UserController userController1=(UserController) context.getBean("userController");userController1.say();//3.通过名字和类型双重查找UserController userController2=context.getBean("userController",UserController.class);userController2.say();}}

之后几个跟controller差不多

方法注解:

使用场景:

1.想修改第三方的无法修改的类

2.想使用多个对象时

代码解释:如此时有个无法修改的第三方类

@AllArgsConstructor//添加一个全参数的构造函数
@NoArgsConstructor//添加一个无参数的构造函数
@Data
public class Student {private String name;private int age;
}

想使用它只能外置一个类:

@Component
public class StudentController {@Beanpublic Student userInfo(){return new Student("zhansan",15);}
}

注意此处的方法注释@Bean必须和任意一个类注释一起使用,要先让spring知道你需要托管.

另外也可以new多个对象,但这里就不能通过类型去取了:

@Component
public class StudentController {@Beanpublic Student userInfo(){return new Student("zhangsan", 20);}@Beanpublic Student userInfo1(){return new Student("lisi", 22);}
}

也可以修改默认名字或者添加复数个名字:

指定扫描路径

在spring搜索bean位置的时候会根据包的存储位置存储

也就是这个,有可能你分的包比较多,让spring无法搜索到你指定的bean,是可以进行修改的:

@ComponentScan("com.example.dome")

总结:

http://www.lryc.cn/news/602746.html

相关文章:

  • 【服务器知识】nginx配置ipv6支持
  • JVM 内存共享区域详解
  • RabbitMQ概念与管理端配置说明
  • 学习游戏制作记录(改进剑投掷状态)7.28
  • 四、计算机组成原理——第7章:输入/输出系统
  • Unity_UI_NGUI_组合控件2
  • 数论1.01
  • socketpair函数详解
  • MCU+RTOS调试
  • STM32-基本定时器
  • JavaScript手录-排序算法篇
  • 二分查找的「左右为难」:如何优雅地找到数组中元素的首尾位置
  • 城阳区奥赛暑假公益班第三次入门组初赛模拟赛
  • 把振动数据转成音频并播放
  • 提取apk中的各种语言翻译成表格,python脚本
  • Lakehouse: Unifying DW Advanced Analytics in Open Platforms
  • 《Java 程序设计》第 8 章 - Java 常用核心类详解
  • 未授权访问漏洞 总结
  • 阿里云【免费试用】Elasticsearch 智能运维 AI 助手
  • python毕业设计案例:基于python django的抖音数据分析与可视化系统,可视化有echarts,算法包括lstm+朴素贝叶斯算法
  • Flutter渲染引擎:Impeller和Skia
  • 低成本嵌入式Linux开发方案:通过配置文件实现参数设置
  • R语言与作物模型(以DSSAT模型为例)融合应用高级实战技术
  • 亚远景-“过度保守”还是“激进创新”?ISO/PAS 8800的99.9%安全阈值之争
  • 11.Dockerfile简介
  • 神经网络CNN、RNN、Transform
  • Avalonia的自定义边框窗口
  • opencv 模块裁剪 按需安装指定模块
  • 火线、零线、地线
  • ICPC 2024 网络赛(I)