SpringBoot框架学习笔记(二):容器功能相关注解详解

Spring 注入组件的注解

@Component、@Controller、 @Service、@Repository这些在 Spring 中的传统注解仍然有效,通过这些注解可以给容器注入组件 

2 @Configuration

2.1 应用实例

需求说明: 演示在 SpringBoot, 如何通过@Configuration 创建配置类来注入组件 

回顾传统方式如何通过配置文件注入组件 

(1)创建 com\springboot\bean\Monster.java

package com.springboot.bean;public class Monster {private Integer id;private String name;private Integer age;private String skill;public Monster(Integer id, String name, Integer age, String skill) {this.id = id;this.name = name;this.age = age;this.skill = skill;}public Monster() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getSkill() {return skill;}public void setSkill(String skill) {this.skill = skill;}@Overridepublic String toString() {return "Monster{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", skill='" + skill + '\'' +'}';}
}

 (2)创建 src\main\resources\beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="monster03" class="com.springboot.bean.Monster"><property name="name" value="牛魔王~"></property><property name="age" value="5000"></property><property name="skill" value="芭蕉扇~"></property><property name="id" value="1000"></property></bean>
</beans>

(3)在主程序中进行测试

ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Monster monster = ioc.getBean("monster03", Monster.class);
System.out.println("monster=" + monster);

运行结果

使用 SpringBoot 的@Configuration 添加/注入组件 

(1)创建 src\main\java\com\springboot\config\BeanConfig.java 

package com.springboot.config;import com.springboot.bean.Monster;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 1. @Configuration 标识这是一个配置类, 等价于配置文件* 2. 程序员可以通过@Bean 注解注入bean对象到容器* 3. 当一个类被 @Configuration 标识,该类-Bean 也会注入容器*/
@Configuration
public class BeanConfig {/*** 1. @Bean : 给容器添加组件, 就是Monster bean* 2. monster01() : 默认方法名monster01 作为Bean的名字/id* 3. Monster : 注入类型, 注入bean的类型是Monster* 4. new Monster(200,"牛魔王",500,"疯魔拳") 注入到容器中具体的Bean信息* 5. @Bean(name = "monster_nmw") : 在配置、注入Bean指定名字/id monster_nmw* 6. 默认是单例注入* 7. 通过 @Scope("prototype")  这样设置就会让每次getBean()返回新的对象,即多例.*///@Bean(name = "monster_nmw")@Bean//@Scope("prototype")public Monster monster01() {return new Monster(200, "牛魔王", 500, "疯魔拳");}}

(2)修改 MainApp.java , 从配置文件/容器获取 bean , 并完成测试

//启动springboot应用程序
ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);//===演示 @Configuration====
Monster monster01 = ioc.getBean("monster01", Monster.class);
Monster monster02 = ioc.getBean("monster01", Monster.class);System.out.println("monster01--" + monster01 + " " + monster01.hashCode());
System.out.println("monster02--" + monster02 + " " + monster02.hashCode());

运行结果

成功注入容器,且两次返回的对象的哈希值相同,可知返回的是同一个对象,即单例 

2.2 @Configuration 注意事项和细节 

(1)配置类本身也是组件, 因此也可以获取

//===演示 配置类也会被注入容器 ====BeanConfig bean = ioc.getBean(BeanConfig.class);
System.out.println("bean--" + bean);

(2)pringBoot2 新增特性: proxyBeanMethods 指定 Full 模式 和 Lite 模式

proxyBeanMethods:代理bean的方法 

  • proxyBeanMethods = true 表示Full模式,保证每个@Bean方法被调用多少次返回的组件都是单实例的, 是代理方式
  • proxyBeanMethods = false 表示Lite模式,每个@Bean方法被调用多少次返回的组件都是新创建的, 是非代理方式
  • 特别说明: proxyBeanMethods 是在 调用@Bean方法才生效,因此,需要先获取BeanConfig 组件,再调用方法。而不是直接通过 SpringBoot 主程序得到的容器来获取bean, 直接通过ioc.getBean() 获取Bean, proxyBeanMethods 值并没有生效
  • 如何选择: 组件依赖必须使用Full模式默认。如果不需要组件依赖使用 Lite模式。默认为 true
  • Lite模 也称为轻量级模式,因为不检测依赖关系,运行速度快 
// 指定Lite模式
@Configuration(proxyBeanMethods = false)
public class BeanConfig {

主程序测试

//===演示@Configuration(proxyBeanMethods = xxx) //1. 先得到BeanConfig组件
BeanConfig beanConfig = ioc.getBean(BeanConfig.class);
Monster monster_01 = beanConfig.monster01();
Monster monster_02 = beanConfig.monster01();
//
System.out.println("monster_01-" + monster_01 + " " + monster_01.hashCode());
System.out.println("monster_02-" + monster_02 + " " + monster_02.hashCode());//直接通过ioc.getBean() 获取Bean, proxyBeanMethods 值并没有生效Monster monster01 = ioc.getBean("monster01", Monster.class);
Monster monster02 = ioc.getBean("monster01", Monster.class);
System.out.println("monster01-" + monster01 + " " + monster01.hashCode());
System.out.println("monster02-" + monster02 + " " + monster02.hashCode());

运行结果

(3)配置类可以有多个, 就和 Spring 可以有多个 ioc 配置文件是一个道理。但是bean的id不能重复

@Import

通过查看@Import 源码可以了解,该注解可以通过指定一个 class类型的数组, 来注入指定类型的Bean

public @interface Import {Class<?>[] value();
}

通过@Import 方式注入的组件, 默认组件id就是对应类型的全类名

1.3.1 应用实例

需求说明: 演示在 SpringBoot, 如何通过 @Import 来注入组件

(1)创建 bean\Cat.java 和 bean\Dog.java 

package com.springboot.bean;public class Cat {
}
package com.springboot.bean;public class Dog {
}

(2)修改 BeanConfig.java 通过@Import 注入组件

// 这样配置即可将 Dog,Cat注入组件
// 默认id为com.springboot.bean.Dog 和 com.springboot.bean.Cat
@Import({Dog.class, Cat.class})

(3)修改 MainApp.java 完成测试

//===测试@Import 使用Dog dogBean = ioc.getBean(Dog.class);
Cat catBean = ioc.getBean(Cat.class);
System.out.println("dogBean--" + dogBean);
System.out.println("catBean--" + catBean);

 运行结果

@Conditional 

4.1 @Conditional 介绍

(1)条件装配:满足 Conditional 指定的条件,则进行组件注入

(2)@Conditional 是一个根注解,下面有很多扩展注解 

4.2 应用实例

需求说明: 演示在 SpringBoot, 如何通过 @ConditionalOnBean 来注入组件,只有在容器中有 name = monster_nmw 的组件时,才注入 dog01

代码实现:

修改 BeanConfig.java , 加入@ConditionalOnBean 条件约束,并完成测试

@Bean
/*** 1. @ConditionalOnBean(name = "monster_nmw") 表示* 2. 当容器中有一个Bean , 名字是monster_nmw (类型不做约束), 就注入dog01这个Dog bean* 3. 如果没有 名字是monster_nmw Bean 就不注入dog01这个Dog bean* 4. @ConditionalOnMissingBean(name = "monster_nmw") 表示在容器中,* 没有 名字/id 为 monster_nmw 才注入dog01这个Bean* 5. @ConditionalOnBean(name = "monster_nmw") 也可以放在配置类上* 表示对该配置类的所有要注入的组件,都进行条件约束.*/
@ConditionalOnBean(name = "monster_nmw")
//@ConditionalOnMissingBean(name = "monster_nmw")
public Dog dog01() {return new Dog();
}

特别说明:@ConditionalOnBean(name = "monster_nmw") 也可以放在配置类上,表示对该配置类的所有要注入的组件,都进行条件约束

主方法中加入测试

//===演示 @ConditionalOnBean 使用 start ====Dog dog01 = ioc.getBean("dog01", Dog.class);
System.out.println("dog01--" + dog01);

运行结果

由运行结果可知,由于容器中没有 name = monster_nmw 的组件,所以 dog01 没有被注入容器

@ImportResource

作用:原生配置文件引入, 也就是可以直接导入 Spring 传统的 beans.xml ,可以认为是 SpringBoot 对 Spring 容器文件的兼容. 

5.1 @ImportResource 应用实例 

需求: 将 beans.xml 导入到 BeanConfig.java 配置类, 并测试是否可以获得 beans.xml 注入/配置的组件 。beans.xml 文件如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="monster03" class="com.springboot.bean.Monster"><property name="name" value="牛魔王~"></property><property name="age" value="5000"></property><property name="skill" value="芭蕉扇~"></property><property name="id" value="1000"></property></bean>
</beans>

(1)创建新的 BeanConfig3.java 来测试, 使用@ImportResource 导入 beans.xml

package com.springboot.config;import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;@Configuration
//导入beans.xml - 就可以获取到beans.xml 中配置的bean
//可以简写为@ImportResource("classpath:beans.xml")
//可以同时导入多个配置文件,如下
//@ImportResource(locations = {"classpath:beans.xml","classpath:beans02.xml"})
@ImportResource(locations = "classpath:beans.xml")
public class BeanConfig3 {
}

(2)在 MainApp.java 测试

//演示@ImportResource 使用 start===System.out.println("monster03 bean 是否存在-" + ioc.containsBean("monster03"));

运行结果

6 @ConfigurationProperties 配置绑定 

说明:使用 Java 读取到 SpringBoot 核心配置文件 application.properties 的内容, 并且把它封装到 JavaBean 中

6.1 应用实例

需求: application.properties 指定的 k-v JavaBean 绑定 

(1)在 application.properties 文件中指定k-v

#设置Furn的属性k-v
#前面的 furn01 是用于指定不同的绑定对象,这样可以在绑定Furn bean属性时
#通过 furn01 前缀进行区分
#furn01.id 中的 id 就是要绑定的 Furn bean的属性值
furn01.id=100
furn01.name=TV
furn01.price=1000.9

(2)创建 bean\furn.java,使用 @ConfigurationProperties 注解完成配置绑定

package com.springboot.bean;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@ConfigurationProperties(prefix = "furn01")
public class Furn {private Integer id;private String name;private Double price;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Double getPrice() {return price;}public void setPrice(Double price) {this.price = price;}
}

(3) controller/FurnController.java

package com.springboot.controller;import com.springboot.bean.Furn;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.annotation.Resource;@Controller
public class FurnController {// 装配到FurnController@Resourceprivate Furn furn;@RequestMapping("/furn")@ResponseBodypublic Furn furn(){return furn;}
}

(4)启动SpringBoot主程序,在浏览器中输入网址 localhost:8080/furn,完成测试。效果如下

  

(5)特别说明,在 Furn 类上注销 @Component 并 在 BeanConfig.java( 也 可 以 是 其 它 配 置 类 ) 配 置 @EnableConfigurationProperties(Furn.class) 或 @Import( Furn.class), 效果一样

6.2 注意事项和细节

(1)如果 application.properties 有中文, 需要转成 unicode 编码写入, 否则出现乱码 

#设置属性 k-v
furn01.id=100
furn01.name=soft_chair\u6c99\u53d1!!
furn01.price=45678.9

(2)使用 @ConfigurationProperties(prefix = "furn01") 会提示如下信息, 但是不会影响使用

(3)解决 @ConfigurationProperties(prefix = "furn01") 提示信息, 在 pom.xml 增加以下依赖, 即可 

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3247409.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

客户端与服务器通讯详解(3):如何选择合适的通讯方式

上篇文章中&#xff0c;我们讲解了客户端与服务器通讯详解&#xff08;2&#xff09;&#xff1a;12种常见通讯方式&#xff0c;重点讲解了http、websocket和RESTful API三种&#xff0c;本文我们继续讲解如何依据场景选择最合适的通讯方式。欢迎友友们点赞评论。 一、客户端服…

微软研究人员为电子表格应用开发了专用人工智能LLM

微软的 Copilot 生成式人工智能助手现已成为该公司许多软件应用程序的一部分。其中包括 Excel 电子表格应用程序&#xff0c;用户可以在其中输入文本提示来帮助处理某些选项。微软的一组研究人员一直在研究一种新的人工智能大型语言模型&#xff0c;这种模型是专门为 Excel、Go…

PDF文件无法编辑?3步快速移除PDF编辑限制

正常来说,我们通过编辑器打开pdf文件后,就可以进行编辑了&#xff61;如果遇到了打开pdf却不能编辑的情况,那有可能是因为密码或是扫描件的原因&#xff61;小编整理了一些pdf文件无法编辑&#xff0c;以及pdf文件无法编辑时我们要如何处理的方法&#xff61;下面就随小编一起来…

JDK新特性(Lambda表达式,Stream流)

Lambda表达式&#xff1a; Lambda 表达式背后的思想是函数式编程&#xff08;Functional Programming&#xff09;思想。在传统的面向对象编程中&#xff0c;程序主要由对象和对象之间的交互&#xff08;方法调用&#xff09;构成&#xff1b;而在函数式编程中&#xff0c;重点…

Vscode中Github copilot插件无法使用(出现感叹号)解决方案

1、击扩展或ctrl shift x ​​​​​​​ 2、搜索查询或翻找到Github compilot 3、点击插件并再左侧点击登录github 点击Sign up for a ... 4、跳转至github登录页&#xff0c;输入令牌完成登陆后返回VScode 5、插件可以正常使用

Android Framework学习笔记(4)----Zygote进程

Zygote的启动流程 Init进程启动后&#xff0c;会加载并执行init.rc文件。该.rc文件中&#xff0c;就包含启动Zygote进程的Action。详见“RC文件解析”章节。 根据Zygote对应的RC文件&#xff0c;可知Zygote进程是由/system/bin/app_process程序来创建的。 app_process大致处…

好用的AI搜索引擎

1. 360AI 搜索 访问 360AI 搜索: https://www.huntagi.com/sites/1706642948656.html 360AI 搜索介绍&#xff1a; 360AI 搜索&#xff0c;新一代智能答案引擎&#xff0c;值得信赖的智能搜索伙伴&#xff0c;为复杂搜索提供专业支持&#xff0c;解锁更相关、更全面的答案。AI…

pyspark使用 graphframes创建图的方法

1、安装graphframes的步骤 1.1 查看 spark 和 scala版本 在终端输入&#xff1a; spark-shell --version 查看spark 和scala版本 1.2 在maven库中下载对应版本的graphframes https://mvnrepository.com/artifact/graphframes/graphframes 我这里需要的是spark 2.4 scala 2.…

古建筑白蚁监测预警系统解决方案

一、概述 白蚁是世界五大害虫之一&#xff0c;俗称“无牙老虎”&#xff0c;能够破坏房屋建筑、园林绿地、农作物等&#xff0c;特别是木结构和砖木结构的古建筑。白蚁的啃食行为会对古建筑造成严重的损坏&#xff0c;严重时甚至会导致建筑倒塌&#xff0c;严重威胁古建筑的安全…

人工智能导论-专家系统

专家系统 概述 本章主要介绍专家系统的概念、原理&#xff0c;创建过程&#xff0c;并补充知识发现与数据挖掘内容 **重点&#xff1a;**专家系统的工作原理和体系结构,知识获取的过程和模式 **难点&#xff1a;**如何设计和创建专家系统 AI第2次高峰(60年代) - 费根鲍姆 …

TCP与UDP网络编程

网络通信协议 java.net 包中提供了两种常见的网络协议的支持: UDP&#xff1a;用户数据报协议(User Datagram Protocol)TCP&#xff1a;传输控制协议(Transmission Control Protocol) TCP协议与UDP协议 TCP协议 TCP协议进行通信的两个应用进程&#xff1a;客户端、服务端 …

昇思25天学习打卡营第16天 | Vision Transformer图像分类

昇思25天学习打卡营第16天 | Vision Transformer图像分类 文章目录 昇思25天学习打卡营第16天 | Vision Transformer图像分类Vision Transform&#xff08;ViT&#xff09;模型TransformerAttention模块Encoder模块 ViT模型输入 模型构建Multi-Head Attention模块Encoder模块Pa…

BiLSTM 实现股票多变量时间序列预测(PyTorch版)

前言 系列专栏:【深度学习&#xff1a;算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域&#xff0c;讨论了各种复杂的深度神经网络思想&#xff0c;如卷积神经网络、循环神经网络、生成对…

三、GPIO口

我们在刚接触C语言时&#xff0c;写的第一个程序必定是hello world&#xff0c;其他的编程语言也是这样类似的代码是告诉我们进入了编程的世界&#xff0c;在单片机中也不例外&#xff0c;不过我们的传统就是点亮第一个LED灯&#xff0c;点亮电阻&#xff0c;电容的兄弟&#x…

【Java项目笔记】01项目介绍

一、技术框架 1.后端服务 Spring Boot为主体框架 Spring MVC为Web框架 MyBatis、MyBatis Plus为持久层框架&#xff0c;负责数据库的读写 阿里云短信服务 2.存储服务 MySql redis缓存数据 MinIO为对象存储&#xff0c;存储非结构化数据&#xff08;图片、视频、音频&a…

防溺水预警系统引领水域安全新篇章

一、系统概述 随着人们对水域活动的需求增加&#xff0c;溺水事故频发&#xff0c;给人们的生命安全带来了严重威胁。然而&#xff0c;如今&#xff0c;一项创新科技正在以强大的功能和无限的潜力引领着水域安全的新篇章。智能防溺水预警系统&#xff0c;作为一种集成了智能感知…

神经网络构造

目录 一、神经网络骨架&#xff1a;二、卷积操作&#xff1a;三、卷积层&#xff1a;四、池化层&#xff1a;五、激活函数&#xff08;以ReLU为例&#xff09;&#xff1a; 一、神经网络骨架&#xff1a; import torch from torch import nn#神经网络 class CLH(nn.Module):de…

【概率论三】参数估计:点估计(矩估计、极大似然法)、区间估计

文章目录 一. 点估计1. 矩估计法2. 极大似然法2.1. 似然函数2.2. 极大似然估计法 3. 评价估计量的标准3.1. 无偏性3.2. 有效性3.3. 一致性 二. 区间估计1. 区间估计的概念2. 正态总体参数的区间估计 参数估计讲什么 由样本来确定未知参数参数估计分为点估计与区间估计 一. 点估…

Golang面试题整理(持续更新...)

文章目录 Golang面试题总结一、基础知识1、defer相关2、rune 类型3、context包4、Go 竞态、内存逃逸分析5、Goroutine 和线程的区别6、Go 里面并发安全的数据类型7、Go 中常用的并发模型8、Go 中安全读写共享变量方式9、Go 面向对象是如何实现的10、make 和 new 的区别11、Go 关…

【Pytorch】RNN for Name Classification

参考学习来自&#xff1a; https://pytorch.org/tutorials/intermediate/char_rnn_classification_tutorial.htmlRNN完成姓名分类https://download.pytorch.org/tutorial/data.zip 导入库 import glob # 用于查找符合规则的文件名 import os import unicodedata import stri…