spring04-管理bean(創建、注入):基于注解

一、什么是注解?

(1)注解的定義

注解(Annotation)是 Java 代碼中的一種特殊標記,用于在程序運行或編譯時提供元信息

格式:

@注解名(屬性名=屬性值, 屬性名=屬性值...)

(2)注解的使用位置

注解可以作用在:

位置示例
類上@Component@Controller
方法上@PostMapping@Bean
屬性上@Autowired@Value

(3)為什么要用注解?

以前 Spring 使用 XML 管理 Bean(如 <bean> 標簽),太繁瑣。

使用注解的目的就是:

  • 減少繁瑣 XML 配置

  • 提高開發效率

  • 實現“零 XML”開發(尤其在 Spring Boot 中)

二、Spring 提供的用于創建 Bean 的注解

Spring 提供四個核心注解來創建 Bean:

(1)@Component
(2)@Service
(3)@Controller
(4)@Repository

上面四個注解功能是一樣的,都可以用來創建 bean 實例。

第一步,引入AOP依賴

        <!-- Spring AOP --><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.3.34</version></dependency>

第二步,在配置文件中,開啟組件掃描

要想讓這些注解生效,必須啟用 組件掃描,告訴 Spring 去哪些包下掃描這些類。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 開啟組件掃描 --><context:component-scan base-package="createBean"/>

1、添加context命名空間

2、開啟組件掃描

第三步,創建類,在類上添加注解。

2-1、@Component

  • 通用組件注解,表示這個類會被 Spring 容器管理。

  • 最基本的注解,其他三個都是它的“語義化子類”。

這四個注解效果都是一樣的,都能實現創建bean,只是語義不同!

@Component
public class UserService {// ...
}

2-2、@Service

  • 用于 業務邏輯層(Service)

  • 語義更清晰,等價于 @Component

@Service
public class OrderService {// 業務處理邏輯
}

2-3、@Controller

  • 用于 控制層(Controller)

  • 和 Spring MVC 一起使用,處理前端請求

@Controller
public class UserController {@RequestMapping("/hello")public String hello() {return "hello.jsp";}
}

2-4、@Repository

  • 用于 數據訪問層(DAO)

  • Spring 會對其進行 異常轉換(把 JDBC 異常轉換為 Spring 的統一異常)

@Repository
public class UserDao {// 數據訪問邏輯
}

2-5、總結:這四個注解有什么關系?

注解說明本質上就是 @Component
@Component通用組件,推薦基礎類使用?
@Service用于 Service 層?(語義化)
@Controller用于 Web 層控制器?(語義化)
@Repository用于 DAO 層?(附帶異常轉換功能)

2-6、精準控制掃描范圍

1、include-filter

2、exclude-filter

三、如何讓 Spring 識別這些注解?

要想讓這些注解生效,必須啟用 組件掃描,告訴 Spring 去哪些包下掃描這些類。

3-1、XML 方式啟用注解掃描:

<context:component-scan base-package="com.example"/>

3-2、Java 配置方式:(完全注解開發)

@Configuration
@ComponentScan("com.example")
public class AppConfig {
}

背景:為什么有這段代碼?

這是 Spring 在**使用注解配置(純 Java 配置)**時,替代 XML 配置的一種方式,用來告訴 Spring:

“這是一個 Java 配置類,它會負責創建和管理 Spring 容器中的 Bean。”

此時,可以用配置類,完全替代xml配置文件,實現完全注解開發!


1、@Configuration 注解詳解

🟡 作用:

@Configuration

用于聲明一個類是 配置類(Configuration Class)等價于以前的 applicationContext.xmlbeans.xml 文件

🟢 本質:

@Configuration 本質上是一個 @Component,因此它本身也會被 Spring 管理為一個 Bean。

  • 會告訴 Spring:“這里面的方法可以用來生成 Bean。”

  • 配合 @Bean 注解使用最常見(手動注冊 Bean)

🧠 舉例:

@Configuration
public class AppConfig {@Beanpublic UserService userService() {return new UserService();  // 相當于 <bean id="userService" class="..."/>}
}

2、@ComponentScan("com.example") 注解詳解

🟡 作用:

告訴 Spring 自動掃描指定包及其子包中的所有注解類(比如 @Component@Service@Controller@Repository),并將它們注冊為 Spring 容器中的 Bean。

🟢 類似于 XML 中的配置:

<context:component-scan base-package="com.example"/>

🧠 舉例:

@ComponentScan("com.example")

表示掃描 com.example 這個包及其子包中的類。

只要類上有下面這些注解之一:

  • @Component

  • @Service

  • @Controller

  • @Repository

Spring 就會自動創建這些類的實例并放入 IoC 容器。


3、完整代碼解釋

@Configuration                        // 聲明這是一個配置類,代替 XML 配置
@ComponentScan("com.example")        // 掃描 com.example 包下的所有注解 Bean
public class AppConfig {// 此類可以寫 @Bean 方法,也可以不寫(只做組件掃描)
}

4、使用方式:怎么讓它生效?

你需要創建一個 Spring 容器,并傳入這個配置類:

// 使用注解方式創建容器(非 XML)
AnnotationConfigApplicationContext context =new AnnotationConfigApplicationContext(AppConfig.class);// 從容器中獲取 Bean
UserService userService = context.getBean(UserService.class);
userService.sayHello();

5、進階補充

(1)、多個包掃描,數組形式!

@ComponentScan(basePackages = {"com.example", "com.other"})

(2)、精準控制掃描范圍(排除特定類)

@ComponentScan(basePackages = "com.example",excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class)
)

6、小結對比(XML vs 注解方式)

功能XML 配置注解配置(現代 Spring 推薦)
聲明配置文件<beans>@Configuration
聲明組件掃描<context:component-scan>@ComponentScan
注冊 Bean<bean>@Bean

7、示意圖結構:

com.example
├── AppConfig.java          // @Configuration + @ComponentScan
├── controller
│   └── HelloController.java  // @Controller
├── service
│   └── HelloService.java     // @Service
└── dao└── UserDao.java          // @Repository

四、基于注解方式實現屬性的注入(Dependency Injection: DI)

Spring 提供多種注解方式來將對象之間的依賴關系注入到類中,最常見的是:

(1)@Autowired

(2)@Qualifier

(3)@Resource(來自 JSR-250,Java 標準)


4-1、@Autowired —— 按類型注入

作用:自動根據類型(byType)在 Spring 容器中查找匹配的 Bean 并注入。

第一步 把 service 和 dao 對象創建,在 service 和 dao 類添加創建對象注解

第二步 在 service 注入 dao 對象,在 service 類添加 dao 類型屬性,在屬性上面使用注解

示例:

@Component
public class UserController {@Autowiredprivate UserService userService;  // 自動注入 UserService 類型的 Bean
}

如果容器中只有一個 UserService 類型的 Bean,就能正常注入。


支持的注入位置:

  • 屬性注入(推薦)

  • 構造函數注入

  • Setter方法注入

1、屬性注入(常用):

@Autowired
private UserService userService;

2、構造函數注入:

@Autowired
public UserController(UserService userService) {this.userService = userService;
}

3、Setter注入:

@Autowired
public void setUserService(UserService userService) {this.userService = userService;
}

?注意:

  • 默認 按類型 注入(byType)

  • 如果找到多個相同類型的 Bean → 會報錯(NoUniqueBeanDefinitionException

?

4、可選注入

默認情況下,當我們標記了一個@Autowired后,Spring如果沒有找到對應類型的Bean,它會拋出NoSuchBeanDefinitionException異常。

可以給@Autowired增加一個required = false的參數:

@Component
public class MailService {@Autowired(required = false)ZoneId zoneId = ZoneId.systemDefault();...
}

這個參數告訴Spring容器,如果找到一個類型為ZoneId的Bean,就注入,如果找不到,就忽略

這種方式非常適合有定義就使用定義,沒有就使用默認值的情況。


4-2、@Qualifier —— 配合 @Autowired 精確指定注入哪一個 Bean(按名字

當容器中有多個相同類型的 Bean 時,用 @Qualifier("beanName") 指定注入哪個。

示例:

@Component("userServiceA")
public class UserServiceA implements UserService {}@Component("userServiceB")
public class UserServiceB implements UserService {}@Component
public class UserController {@Autowired@Qualifier("userServiceA")private UserService userService;  // 明確注入 userServiceA
}

【注意】:

? ? ?@Qualifier 只能和 @Autowired 搭配使用


4-3、@Resource —— 按名字注入(來自 JSR-250)

來自 Java 標準規范(javax.annotation.Resource),也被 Spring 支持。

默認注入規則:

  • 先按 名字(byName)找 Bean

  • 如果找不到,再按類型(byType)找。

示例:

@Resource(name = "userService")
private UserService userService;

如果沒寫 name 屬性:

Spring 默認使用變量名作為 Bean 名稱:

@Resource
private UserService userService;  // 默認去找名為 "userService" 的 Bean

4-4、三者對比總結:

特性@Autowired@Qualifier@Resource
來自包Spring(org.springframeworkSpringJDK(javax.annotation
注入方式默認按類型(byType)搭配 @Autowired 使用,按名稱默認按名稱(byName),找不到再按類型
支持位置屬性、構造器、方法搭配 @Autowired 使用屬性、方法(不推薦構造器)
是否必須默認必須,配合 @Autowired(required = false) 可設為非必須-默認必須,可搭配 @Resource(name="...") 使用

推薦使用方式(Spring 開發建議)

  • 單一 Bean 時:直接用 @Autowired

  • 多個實現類時:用 @Autowired + @Qualifier

  • 需要兼容 JDK 標準規范時:用 @Resource(這不是spring官方的注解,是javax里面的)


4-5、例子完整演示

@Service("userServiceA")
public class UserServiceA implements UserService {}@Service("userServiceB")
public class UserServiceB implements UserService {}@Controller
public class UserController {// 推薦使用方式一@Autowired@Qualifier("userServiceA")private UserService userService;// 或者使用標準注解方式// @Resource(name = "userServiceB")// private UserService userService;
}

4-6、@Value注解

以上的三個注解,都是屬性類型是對象的注解,當屬性類型是普通數據類型的時候,可以使用@Value注解。

除此以外,@Value還可以注入:

  • 字面量(常量、字符串等)

  • 配置文件中的值(.properties.yml 中)

  • SpEL 表達式(Spring Expression Language)

當然可以!下面是對 @Value 注解的詳細講解,幫助你全面理解它的作用、用法和使用場景:


1、常見使用場景

(1)注入常量值
@Value("Hello Spring")
private String msg;

(2)注入配置文件中的值(最常見

假設有 application.properties 文件:

app.name=SmartCampus
app.version=1.0.2

然后在 Java 類中使用:

@Component
public class AppInfo {@Value("${app.name}")private String appName;@Value("${app.version}")private String version;
}

Spring 會自動從配置文件中找到 app.name 對應的值并注入。


(3)、使用條件

.properties 文件必須加載進 Spring 容器中!!!

如果你使用的是 Spring Boot → 它自動加載了 application.properties不需要額外配置

但如果你是傳統 Spring XML 項目:

<context:property-placeholder location="classpath:application.properties"/>

【回顧】:

這是spring加載外部配置文件的方式!?


(4)、支持 SpEL 表達式(計算、引用 Bean 等)

示例 1:表達式計算

@Value("#{5 * 2}")
private int result;  // result = 10

示例 2:引用其他 Bean 的屬性

@Value("#{userService.name}")
private String userName;

注意觀察#{}這種注入語法,它和${key}不同的是,#{}表示從JavaBean讀取屬性

示例:"#{smtpConfig.host}"的意思是,從名稱為smtpConfig的Bean讀取host屬性,即調用getHost()方法。

使用一個獨立的JavaBean持有所有屬性,然后在其他Bean中以#{bean.property}注入的好處是,多個Bean都可以引用同一個Bean的某個屬性。


(5)、也可以用在方法或構造器參數
@Component
public class Server {private int port;public Server(@Value("${server.port}") int port) {this.port = port;}
}

(6)、@Value 注入數組、集合

示例:

app.languages=Java,Python,R
@Value("#{'${app.languages}'.split(',')}")
private List<String> languages;

(7)、小結
注解用途
@Value注入屬性值(字面量、配置、SpEL)
${}取配置文件中的值
#{}SpEL 表達式(計算、引用等)

五、創建第三方Bean

Spring 中一個非常典型的場景:

?如何將一個沒有使用 @Component 注解的第三方類(如 HikariDataSource)交給 Spring IoC 容器管理?

因為第三方類你無法直接修改源代碼(不能加 @Component),所以不能自動掃描識別。我們需要用 顯式注冊的方式 告訴 Spring 去創建并管理這個 Bean。


解決方案:使用 @Configuration + @Bean 創建第三方 Bean。

即:

我們自己在@Configuration類中編寫一個Java方法創建并返回它,注意給方法標記一個@Bean注解:

你可以在一個 Java 配置類中,手動創建并配置 HikariDataSource,然后交給 Spring 容器管理。


示例代碼:創建并注入 HikariDataSource

步驟 1:添加依賴(Spring + HikariCP)

Maven 依賴示例:

<dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId><version>5.1.0</version>
</dependency>

步驟 2:配置文件 application.properties

db.url=jdbc:mysql://localhost:3306/test
db.username=root
db.password=123456

步驟 3:Java 配置類 AppConfig.java

@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {@Value("${db.url}")private String jdbcUrl;@Value("${db.username}")private String username;@Value("${db.password}")private String password;// 手動創建 HikariDataSource@Beanpublic HikariDataSource dataSource() {HikariDataSource ds = new HikariDataSource();ds.setJdbcUrl(jdbcUrl);ds.setUsername(username);ds.setPassword(password);return ds;}// 如果你有 UserService 也可以在這里注入@Beanpublic UserService userService(HikariDataSource dataSource) {return new UserService(dataSource);}
}

【注意】:

Spring對標記為@Bean的方法只調用一次,因此返回的Bean仍然是單例。?


使用方式:

AnnotationConfigApplicationContext context =new AnnotationConfigApplicationContext(AppConfig.class);UserService userService = context.getBean(UserService.class);
userService.doSomething();

小結:創建第三方 Bean 的三種常見方法

方法使用場景示例
@Bean 方法最推薦方式,靈活、清晰、能配置參數@Bean public HikariDataSource dataSource() { ... }
XML 配置傳統 Spring 項目可用<bean class="com.zaxxer.hikari.HikariDataSource" .../>

總結:

如果我們想給 UserService 注入一個來自第三方包(如 HikariDataSource)的 Bean:

  • 使用 @Configuration

  • 編寫 @Bean 方法創建并配置 HikariDataSource

  • 然后通過構造器或 @Autowired 注入到其他組件中

?【注意】:

????????在 Spring Boot 項目中,如果你想將一個第三方類(比如 HikariDataSource)注入到自己的類中,通常你只需要:

1、添加maven依賴

2、使用 @Autowired 就可以注入使用了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/86849.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/86849.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/86849.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

docker安裝elasticsearch和kibana

elasticsearch版本和kibana版本需保持一致。這里我使用的都是8.18.2 安裝elasticsearch docker-compose.yml networks:es-net: external: true services:elasticsearch:container_name: es01deploy:resources:limits:cpus: 0memory: 0environment:- discovery.typesingle-no…

Python爬蟲實戰:研究sanitize庫相關技術

1. 引言 1.1 研究背景與意義 在當今數字化時代,互聯網已成為人們獲取信息、交流互動的重要平臺。隨著 Web 2.0 技術的發展,用戶生成內容 (UGC)、社交媒體嵌入、第三方插件等功能極大豐富了網頁的內容和交互性,但也帶來了嚴峻的安全挑戰。根據 Web 應用安全聯盟 (WAS) 的統…

c++ 學習(二、結構體)

目錄 一、結構體與const 二、結構體與class的區別 參考鏈接&#xff1a;69 結構體-結構體中const使用場景_嗶哩嗶哩_bilibili 一、結構體與const 調用函數的時候&#xff0c;希望這個結構體是可讀而不可寫的時候&#xff0c;傳指針&#xff0c;使用const修飾&#xff0c;方式…

機器學習開篇:算法分類與開發流程

種一棵樹最好的時間是十年前&#xff0c;其次是現在。 一、機器學習算法分類 機器學習&#xff08;ML&#xff0c;Meachine Learning&#xff09;是人工智能的核心領域&#xff0c;讓計算機從數據中學習規律并做出預測&#xff0c;本文簡單介紹機器學習的算法分類和開發流程。…

使用pyflink編寫demo并將任務提交到yarn集群

目錄 背景 一、pyflink安裝 二、編寫demo程序 三、提交yarn前準備 四、提交任務 五、踩坑記錄 1、提交任務時客戶端出現語法錯誤 2、提交任務時客戶端出現lzma包找不到 3、提交任務時客戶端出現“org.apache.flink.streaming.api.utils.PythonTypeUtils.getCollectionIn…

Vue 3 最基礎核心知識詳解

Vue3作為現代前端主流框架&#xff0c;是前后端開發者都應當掌握的核心技能。本篇文章將帶你了解vue3的基礎核心知識&#xff0c;適合學習與復習 一、Vue 3 應用創建 1.1 創建Vue應用的基本步驟 // main.js import { createApp } from vue // 1. 導入createApp函數 import …

Bootstrap 5學習教程,從入門到精通,Bootstrap 5 Flex 布局語法知識點及案例(27)

Bootstrap 5 Flex 布局語法知識點及案例 Bootstrap 5 提供了強大的 Flexbox 工具集&#xff0c;讓布局變得更加簡單靈活。以下是 Bootstrap 5 Flex 布局的完整知識點和詳細案例代碼。 一、Flex 布局基礎語法 1. 啟用 Flex 布局 <div class"d-flex">我是一個…

HarmonyOS 5智能單詞應用開發:記憶卡(附:源碼

一、應用概述與核心價值 在語言學習過程中&#xff0c;單詞記憶是基礎也是難點。本文介紹的智能單詞記憶卡應用通過創新的交互設計和科學的學習模式&#xff0c;幫助用戶高效記憶單詞。應用采用ArkUI框架開發&#xff0c;主要特點包括&#xff1a; 雙模式學習系統&#xff1a…

LeetCode--38.外觀數列

前言&#xff1a;之前我不是說&#xff0c;我后續可能會講一下遞歸嗎&#xff0c;現在它來了&#xff0c;這道題會用到回溯的方法&#xff0c;并且比較純粹哦 解題思路&#xff1a; 1.獲取信息&#xff1a;&#xff08;下面這些信息差不多是力扣上面的題目信息了&#xff0c;所…

服務器的安裝與安全設置

1&#xff1a;安裝操作系統 1、創建虛擬機Win49&#xff08;49為序號&#xff09;&#xff0c;并安裝Windows Server 2019操作系統 參考配置&#xff1a;安裝系統的分區大小為20GB&#xff0c;其余分區暫不劃分&#xff0c; 文件系統格式為NTFS&#…

Sensodrive SensoJoint機器人力控關節模組抗振動+Sensodrive力反饋系統精準對接

Sensodrive成立于2003年&#xff0c;起源于德國航空航天中心&#xff08;DLR&#xff09;的LBR項目。公司由一批傳感器技術專家創立&#xff0c;專注于高精度工業扭矩傳感器的研發。憑借二十余年的技術積累&#xff0c;Sensodrive將DLR輕型機器人扭矩技術引入工業領域&#xff…

【AI實踐】Mac一天熟悉AI模型智能體應用(百煉版)

25.6.29增加Gummy 實時/一句話語音識別25.6.28增加Qwen TTS本地音頻和實時播報 背景 準備環境 MacOS M1電腦&#xff08;其他M系列芯片也可以&#xff09; 為了方便python的使用環境&#xff0c;使用Miniconda&#xff1a;下載鏈接&#xff1a;Download Anaconda Distribution…

WEB安全--Java安全--jsp webshell免殺1

1.1、BCEL ClassLoader 介紹&#xff08;僅適用于BCEL 6.0以下&#xff09;&#xff1a; BCEL&#xff08;Apache Commons BCEL?&#xff09;是一個用于分析、創建和操縱Java類文件的工具庫&#xff1b;BCEL的類加載器在解析類名時會對ClassName中有$$BCEL$$標識的類做特殊處…

Valkey與Redis評估對比:開源替代方案的技術演進

#作者&#xff1a;朱雷 文章目錄 1 概述1.1內存數據結構存儲核心特性1.2主流內存數據結構存儲設計與適用場景1.3目前主流內存數據結構存儲對比 2 Valkey 說明2.1 哨兵架構設計2.2 集群架構設計2.3 valkey 使用企業和業內生態? 3 評估指標4 評估結果 1 概述 內存數據結構存儲…

華為云Flexus+DeepSeek征文 | 基于華為云ModelArts Studio安裝NoteGen AI筆記應用程序

華為云FlexusDeepSeek征文 | 基于華為云ModelArts Studio安裝NoteGen AI筆記應用程序 引言一、ModelArts Studio平臺介紹華為云ModelArts Studio簡介ModelArts Studio主要特點 二、NoteGen介紹NoteGen簡介主要特點 三、安裝NoteGen工具下載NoteGen軟件安裝NoteGen工具 四、開通…

BUUCTF在線評測-練習場-WebCTF習題[BJDCTF2020]Easy MD51-flag獲取、解析

解題思路 打開靶場&#xff0c;有個提交框&#xff0c;輸入后url會出現我們提交的參數password http://a48577ed-9a1c-4751-aba0-ae99f1eb8143.node5.buuoj.cn:81/leveldo4.php?password123 查看源碼并沒用發現什么貓膩&#xff0c;抓包在響應頭發現了貓膩 hint: select * …

面向對象三大特性深度解析:封裝、繼承與多態

面向對象三大特性深度解析&#xff1a;封裝、繼承與多態 思維導圖概覽 #mermaid-svg-v2u0XIzKotjyXYei {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-v2u0XIzKotjyXYei .error-icon{fill:#552222;}#mermaid-svg-v2…

mmap映射物理內存之三invalid cache

目錄 流程設計 invalid 命令 內核態invalid 內核態invalid&#xff0c;用戶態mmap物理地址 PAN機制 PAN機制歷程 硬件支持 ARMv8.1-PAN 特性 Linux 內核的適配 軟件模擬 PAN&#xff08;SW PAN&#xff09; 背景 Linux 的實現 總結 前述刷新cache的流程也同樣可…

記憶化搜索(dfs+memo)無環有向圖

這是一道可以當作板子的極簡記憶化搜索 建立a 是鄰接表&#xff0c;其中 a[x] 存儲從節點 x 出發能到達的所有節點。 b[x] 記錄從節點 x 出發的所有邊的權重之和。根據數學原理&#xff0c;我們很容易發現&#xff0c;一個根&#xff08;起點&#xff09;的期望&#xff0c;等…

使用AI豆包寫一個車輛信息管理頁面

記錄一個基本的車輛信息管理頁面&#xff0c;由豆包撰寫完成&#xff0c;只需要微調頁面即可。 主要功能是車輛信息的查詢、新增、編輯&#xff0c;項目用到了uniapp、vue3、ts、uni-ui、z-paging 頁面效果如下&#xff1a; 以上界面均由豆包生成&#xff0c;完成度非常高&am…