SpringBoot 基础(Spring)

ops/2025/2/1 18:26:24/

SpringBoot 基础(Spring)

Bean 注解标记和扫描 (IoC)


配置类概念

  • @SpringBootConfiguration 或者 @Configuration 注解标注的类就是配置类
  • 配置类本身也会加入 IoC 容器*
@Configuration
public class configuration1 {}@SpringBootConfiguration
public class configuration1 {}

标记 Bean

Spring 提供多种注解用于定义 Bean:

  • @Component:通用注解,标记类为 Spring Bean,可用于各层,如 Service、Dao 等,直接标注在类上即可。
  • @Repository:专用于 Dao 层类,
  • @Service:用于 Service 层类,
  • @Controller:用于 Controller
    .

注意: 源码显示,@Controller、@Service、@Repository 基于 @Component 起名,对 Spring IOC 管理无实质区别,仅为方便开发者区分组件作用。虽本质相同,但为保证代码可读性与结构严谨性,不可随意标注。

@Component
public class CommonComponent {}@Controller
public class XxxController {}@Repository
public class XxxDao {}@Service
public class XxxService {}

扫描 Bean

SpringBoot 主程序的 @SpringBootApplication 会自动扫描 Bean

SpringBootAplication 整合了以下注解

  • @SpringBootConfiguration —— 表示这个类本身是个配置类
  • @EnableAutoConfiguration —— 自动加载其他的配置类
  • @ComponentScan 默认是扫描当前类所在的包和子包
    • 自定义一个 @ComponentScan(basePackages = "包1", "包2")
    • 或者 @SpringBootApplication(scanBasePackages = "包1", "包2")
//@SpringBootConfiguration //表示这个类本身是个配置类
//@EnableAutoConfiguration //自动加载其他的配置类
//@ComponentScan //默认是扫描当前类所在的包和子包
@SpringBootApplication
public class Boot302DemoApplication {public static void main(String[] args) {var ioc = SpringApplication.run(Boot302DemoApplication.class, args);}}

第三方组件加入 IoC 容器

第一种方法:@Bean

第三方 jar 我们不可能直接在源码加 @Component 所以需要用 @Bean 标签

  • @Bean:方法返回值作为 Bean 类型:在使用 @Bean注解 的方法中,方法的返回值类型决定了 Bean 的类型。
  • 例如,如果方法返回一个DataSource 类型的对象,那么这个 BeanSpring 容器中的类型就是 DataSource。这个类型可以是 具体的类,也可以是 接口 或者 抽象类

.
注意:@Bean 只能在配置类里面写。当然不仅是第三方 jar 普通的也行

@Configuration
public class AppConfig {//@Beanpublic FastsalException fastsalException() {return new FastsqlException();}
}
第二种方式:@Import

快速把类放入 IoC 容器 (第三方或者自己的类都可以)。常用于整合配置类等操作。

  • 配置类放进 IoC 容器相比与配置类配置的所有组件都会放进 IoC 容器

  • 也只能在配置类中使用

@Configuration
@Import(FastsalException.class) //快速把第三方地 FastsalException类放入 IoC 容器
public class AppConfig {}

BeanBeanName 问题

@ComponentBeanName

  • 默认情况:和首字母小写的类名相同。 例如:SoldierController 类对应的 bean 的 id 就是 soldierController
  • 自己指定:@Controller( value = "BeanName")

@BeanBeanName

  • 默认情况:和方法名相同
  • 自己指定:@Bean("BeanName")

Bean 的初始化和销毁方法

我们可以在组件类中定义方法,然后当 IoC 容器 实例化和销毁组件 对象的时候进行自动调用!这两个方法我们称为为生命周期方法!
.
类似于Servlet的 init/destroy 方法, 我们可以在周期方法完成初始化和释放资源等工作。

第一种:直接声明

//只要有 Bean 初始化和销毁了就执行这里的两个方法
public class BeanOne {//周期方法要求: 方法命名随意,但是要求方法必须是 public void 无形参列表@PostConstruct  //注解制指定初始化方法public void init() {// 初始化逻辑}@PreDestroy //注解指定销毁方法public void cleanup() {// 释放资源逻辑}}

第二种:通过 @Bean 指定

public class BeanOne {public void init() {// initialization logic}
}public class BeanTwo {public void cleanup() {// destruction logic}
}@Configuration
public class AppConfig {@Bean(initMethod = "init")public BeanOne beanOne() {return new BeanOne();}@Bean(destroyMethod = "cleanup")public BeanTwo beanTwo() {return new BeanTwo();}
}

Bean 的单例和多例问题

取值含义创建对象的时机默认值
singleton在 IOC 容器中,这个 bean 的对象始终为单实例IOC 容器初始化时
prototype这个 bean 在 IOC 容器中有多个实例获取 bean 时

第一种方式:全名声明

//ConfigurableBeanFactory.SCOPE_PROTOTYPE 就是多例
//单例模式就是只要实例化一个 bean 就执行一次
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE) // 单例
@Component
public class JavaBean {}

第二种方式:简洁声明

@Scope("prototype") // 单例
@Component
public class JavaBean {}

两者区别

  • @Scope("prototype")
    • 对于初学者或简单项目,使用字符串的方式可能更容易理解和书写,但是在大型项目中,如果作用域名称拼写错误(例如写成 “prototyp”),编译器不会给出错误提示,可能导致运行时问题。
  • @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    • 使用 ConfigurableBeanFactory.SCOPE_PROTOTYPE 常量可以避免拼写错误,因为 IDE 会在编译时检查该常量是否存在,同时也更符合 Java 编程的最佳实践,即使用常量而不是硬编码字符串。

Bean 依赖注入:引用类型自动装配(DI)


前提条件:参与自动装配的组件,无论是要被装配的还是提供装配的,都必须在 IoC 容器里,并且 IoC 容器的实现方式(XML 配置或者注解方式)对此没有影响。

@Autowired:按照类型装配

  • @Autowired 注解使用方法:可以直接在成员变量上标记 @Autowired 注解 来自动注入对象,在实际项目中我们通常采用这种方式。甚至第三方类放入容器后,也能使用此注解来实现自动装配。

  • 原理

    • 在 ioc 容器中查找符合类型的组件对象
    • 设置给当前属性(di)
  • @Autowired 标记的位置:成员变量,get方法, 构造器

  • Bean
@Repository
public class UserDao {}@Service
public class UserService {private UserDao userDao;public UserDao getUserDao() {return userDao;}
}
  • @Autowired 注入
@Service
public class UserService {//这里相当于注入了 UserDao 类型的对象@Autowiredprivate UserDao userDao;public UserDao getUserDao() {return userDao;}
}

@Autowired 装配流程
·
在这里插入图片描述

@Qualifier:指定 BeanName 装配

根据 @Qualifier 注解中指定的名称作为 BeanName 进行匹配。需要配合 @Autowired

@Repository
public class UserDao {private UserDao userDao;//匹配 BeanName 为 userDao 进行装配//value 可以省略@Autowired@Qualifier(value = "userDao")public void setUserDao(UserDao userDao) {this.userDao = userDao;}
}

@Resource:多功能装配

  • 如果没有指定 name, 先根据 属性名 查找 IoC 中组件
  • 如果没有指定 name, 并且属性名没有对应的组件, 会根据 属性类型 查找
  • 如果指定name名称查找。Resource(name='test') == @Autowired + @Qualifier(value='test')
Repository
public class UserDao {@Resource(name = "userDao")private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}
}

@Bean 声明组件之间的装配

第一种方式:直接调用方法

如果其他组件也是 @Bean 方法 也可以 直接的调用方法这个本质上从 IoC 容器获取组件

  • POJO
public class Money {}public class People {private Money money;public void setMoney(Money money) {this.money = money;}
}
  • 配置类
@SpringBootConfiguration
public class configuration1 {@Beanpublic Money money() {return new Money();}@Beanpublic People people() {People people = new People();//直接调用方法本质上从 ioc 容器获取组件people.setMoney(money());return people;}}
第二种方式:形参列表自动注入

形参列表声明自动注入

  • 要求必须有对应的类型的组件, 如果没有抛异常
  • 如果有多个同类型的 Bean 。可以使用 形参名称 = 对应的 beanName 的方式
  • POJO
public class Money {}public class People {private Money money;public void setMoney(Money money) {this.money = money;}
}
  • 配置类
@SpringBootConfiguration
public class configuration1 {@Bean //默认方法名就是BeanNamepublic Money money() {return new Money();}@Beanpublic People people(Money money) {People people = new People();people.setMoney(money);return people;}}

Bean 依赖注入:基本类型装配(DI)


第一种方式:@Value 直接绑定

  • @Value 是 Spring 框架中的一个注解,其主要作用是将外部配置文件中的具体值注入到由 Spring 管理的组件的字段中。这里所说的 Spring 管理的组件,通常是指带有 @Component 注解的类。
  • 具体使用时,在字段上添加 @Value("${某个属性名}") 注解。当 Spring 应用启动时,它会自动从配置文件里查找与注解中指定属性名相对应的值,并将该值填充到使用 @Value 注解标注的字段中。
    .

使用

  • 情况1:${key} 取外部配置 key 对应的值!
  • 情况2:${key : defaultValue} 没有 key, 可以给与默认值
  • properties 配置文件
username=mangfu
gender=男
age=20
  • 开始注入
@Component
//导入 properties配置文件
@Data
public class MyComponent {//注入@Value("${username}")private String name;@Value("${age}")private String age;@Value("${gender}")private String gender;}

第二种方式:@configurationProperteis 根据前缀绑定

@ConfigurationProperties

前提是要用 @Component 或者 @Bean 把类加入 IoC 容器。并且有 get set 方法

  • application.properties
pig.id=1
pig.name=佩奇
pig.age=5
  • @Component 方式
@Data
//必须加入 IoC 容器 @ConfigurationProperties(prefix = "pig") 才生效
@Component
//根据前缀为 pig 的自动匹配和 properties 一样的后缀然后赋值
@ConfigurationProperties(prefix = "pig")
public class Sheep {private Long id;private String name;private Integer age;}
  • @Bean 方式
@Configuration
public class AppConfig2 {@ConfigurationProperties(prefix = "pig")@Beanpublic Pig pig() {return new Pig();}
}
@EnableConfigurationProperties

Spring Boot 默认只扫描主程序所在包,导入第三方包时,即便组件标有 @Component@ConfigurationProperties,也因扫描不到而无法完成属性绑定和注册到容器。
.

使用 @EnableConfigurationProperties(Sheep.class) 可快速对指定类(如 Sheep 类)进行属性绑定并注册到容器。
,
使用该注解需注意:

  • 先使用 @ConfigurationProperties(prefix = " ") 绑定指定类。
  • 在配置类中使用。
  • Application.properties
sheep.id=1
sheep.name=苏西
sheep.age=5
  • POJO
//可以不用 @Component 加入 IoC 容器。等下 @EnableConfigurationProperties 会把它加入 IoC并赋值 
@ConfigurationProperties(prefix = "sheep")
public class Sheep {private Long id;private String name;private Integer age;}
  • 配置类
//这里就把 Sheep 加入 IoC 容器并且对应赋值了
@EnableConfigurationProperties(Sheep.class)
public class AppConfig2 {}

@ConditionalOnXXX 条件判断注解


如果注解指定的条件成立,则触发指定行为

  • @ConditionalOnClass:如果类路径中存在这个类,则触发指定行为

  • @ConditionalOnMissingClass:如果类路径中不存在这个类,则触发指定行为

  • @ConditionalOnBean:如果容器中存在这个Bean(组件),则触发指定行为

  • @ConditionalOnMissingBean:如果容器中不存在这个Bean(组件),则触发指定行为

  • @ConditionalOnBean(value=组件类型,name=组件名字):判断容器中是否有这个类型的组件,并且名字是指定的值

.
如果是类级别就。类里所有操作都执行或不执行

举例

@SpringBootConfiguration
public class AppConfig {//类路径中存在这个类就创建这个 Bean 			 @ConditionalOnClass(name="com.atguigu.boot.controller.HelloController.class")@Beanpublic Money money() {return new Money();}//类路径中不存在这个类就创建这个 Bean 	@ConditionalOnMissingClass(value ="com.atguigu.boot.controller.HelloController.class")@Beanpublic People person() {return new People();}
}

SpringBoot 获取 Bean


之前我们用的是 AnnotationConfigApplicationContext。现在 主程序SpringApplication.run 返回的是 ConfigurableApplicationContextConfigurableApplicationContext接口类型
.

AnnotationConfigApplicationContextConfigurableApplicationContextConfigurableApplicationContext 的具体实现类。所以相当于直接创建好了 ApplicationContext 了我们直接获取 IoC 中的容器就行

第一种方式:根据 BeanName 获取

直接根据 beanName 获取即可 返回值类型是 Object 需要强转 【不推荐】

Object happyConponent = applicationContext.getBean("happyComponent");

第二种方式:根据 BeanName 同时定制 Class

HappyComponent happyComponent1 = applicationContext.getBean("happyComponent", HappyComponent.class);

第三种方式:直接根据类型获取

直接根据类型获取

  • 条件1:同一个类型, 在 Ioc 容器中只能有一个 Bean,如果 IoC 容器中存在多个同类型的 Bean 会出现: NoUniqueBeanFinitionException
  • 条件2IoC 的配置一定是实现类, 但是可以通过接口类型获取触发多态
    .

原理:根据类型来获取 Bean 时,在满足 Bean 唯一性的前提下,其实只是看:【对象 instanceof 指定的类型】的返回结果,只要返回的是 true 就可以认定为和类型匹配,能够获取到。

//A 是接口 HappyComponent 是实现类
A bean = applicationContext.getBean(A.class);
bean.doWork();

http://www.ppmy.cn/ops/154815.html

相关文章

探索AI在SEO关键词优化中的创新应用与成功案例分析

内容概要 在数字化时代,搜索引擎优化(SEO)的重要性不断上升,而人工智能(AI)的出现则为这一领域带来了革命性的变革。本文旨在深入探讨AI在SEO关键词优化中的应用,揭示其如何通过智能化的方式提…

Ubuntu下的Doxygen+VScode实现C/C++接口文档自动生成

Ubuntu下的DoxygenVScode实现C/C接口文档自动生成 Chapter1 Ubuntu下的DoxygenVScode实现C/C接口文档自动生成1、 Doxygen简介1. 安装Doxygen1)方法一:2)方法二:2. doxygen注释自动生成插件3. doxygen注释基本语法4. doxygen的生成…

在docker上部署nacos

一、首先下载nacos的docker镜像 docker pull nacos:2.5.0 二、然后下载nacos的安装包,这里是为了拿到他的配置文件。下载完解压缩后,以备后用 https://download.nacos.io/nacos-server/nacos-server-2.5.0.zip?spm5238cd80.6a33be36.0.0.2eb81e5d7mQ…

基于SpringBoot的租房管理系统(含论文)

基于SpringBoot的租房管理系统是一个集订单管理、房源信息管理、屋主申诉处理、用户反馈等多项功能于一体的系统。该系统通过SpringBoot框架开发,拥有完善的管理员后台、屋主管理模块、用户功能模块等,适用于房地产租赁平台或中介公司进行日常管理与运营…

神经网络和深度学习

应用 类型 为什么近几年飞速发展 数据增长,算力增长,算法革新 逻辑回归 向量化 浅层神经网络(Shallow neural network) 单条训练数据前向传播计算表达式 batch训练数据前向传播计算表达式 反向传播计算表达式 参数随机初始化 不能全部设为0 原因是同一…

DeepSeek-R1 论文解读 —— 强化学习大语言模型新时代来临?

近年来,人工智能(AI)领域发展迅猛,大语言模型(LLMs)为通用人工智能(AGI)的发展开辟了道路。OpenAI 的 o1 模型表现非凡,它引入的创新性推理时缩放技术显著提升了推理能力…

webpack 打包自己的--windows

第一步安装node 1、安装nodejs:https://nodejs.org/zh-cn/download/releases/ 一、Window系统配置: 打开命令窗口,进入当前工程目录 npm配置淘宝镜像:npm config set registry http://registry.npm.taobao.org/ npm安装parcel-bundler:npm install -g parcel-bund…

简要介绍C++中的 max 和 min 函数以及返回值

简要介绍C中的 max 和 min 函数 在C中&#xff0c;std::max 和 std::min 是标准库 <algorithm> 中提供的函数&#xff0c;用于比较两个或多个值并返回最大值或最小值。这些函数非常强大且灵活&#xff0c;支持多种数据类型&#xff08;如整数、浮点数、字符串等&#xff…