最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot配置類注解@Configuration, @Bean用法解讀

 更新時(shí)間:2026年05月02日 14:11:40   作者:han_hanker  
本文通過對(duì)比@Component和@Configuration,解釋了Spring框架的依賴注入(DI)方式,并介紹了@Configuration和@Bean的方法的用法、特點(diǎn)和區(qū)別,舉了驗(yàn)證碼生成器的例子,介紹了@Configuration如何集中管理Bean的創(chuàng)建邏輯,替代了傳統(tǒng)的XML配置

SpringBoot配置類注解@Configuration, @Bean

@Configuration 是 Spring 的核心注解之一,用于:

標(biāo)識(shí)一個(gè)類為 配置類(替代傳統(tǒng)的 XML 配置文件)

允許在其中通過 @Bean 方法 聲明并初始化 Spring 容器中的 Bean

@Configuration
public class KaptchaConfig {

    @Bean(name = "captchaProducer")
    public DefaultKaptcha captchaProducer() {
        Properties props = new Properties();
        props.put("kaptcha.image.width", "200");
        props.put("kaptcha.textproducer.char.string", "0123456789");

        Config config = new Config(props);
        DefaultKaptcha kaptcha = new DefaultKaptcha();
        kaptcha.setConfig(config); // ← 必須手動(dòng)調(diào)用
        return kaptcha;
    }
}
@RestController
public class CaptchaController
{
    @Resource(name = "captchaProducer")
    private Producer captchaProducer;

    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;

Java 中使用 Spring 框架的依賴注入(DI)方式,

通過 @Resource 注解按名稱注入兩個(gè)名為 “captchaProducer” 和 “captchaProducerMath” 的 Producer 類型的 Bean。

這個(gè)結(jié)構(gòu)是不是眼熟

前面我們講@Component 和 @Autowired 很像

1、定位不同

在 Spring 框架中,@Configuration 和 @Component 都可以將一個(gè)類注冊(cè)為 Spring 容器中的 Bean,但它們的設(shè)計(jì)目的、使用場(chǎng)景和內(nèi)部行為有本質(zhì)區(qū)別。以下是核心對(duì)比:

注解用途典型場(chǎng)景
@Component通用組件注解,用于標(biāo)記任意業(yè)務(wù)類(如 Service、DAO、Util 等)為 Spring Bean@Service, @Repository, @Controller 都是 @Component 的派生注解
@Configuration專門用于定義配置類,通常包含 @Bean 方法來聲明和初始化其他 Bean替代 XML 配置文件,集中管理 Bean 的創(chuàng)建邏輯

2、對(duì) @Bean 方法的處理方式不同(關(guān)鍵區(qū)別!)

  • @Configuration 類中的 @Bean 方法:

Spring 會(huì)通過 CGLIB 動(dòng)態(tài)代理 增強(qiáng)該類。

當(dāng)你在同一個(gè)配置類中調(diào)用另一個(gè) @Bean 方法時(shí),不會(huì)創(chuàng)建新對(duì)象,而是從 Spring 容器中返回已存在的單例 Bean。

保證了 @Bean 方法的單例語義。

  • @Component 類中的 @Bean 方法:

不會(huì)被代理,調(diào)用 @Bean 方法相當(dāng)于普通 Java 方法調(diào)用。

每次調(diào)用都會(huì)創(chuàng)建一個(gè)新對(duì)象,繞過 Spring 容器的管理。

無法保證單例,可能導(dǎo)致意外的多實(shí)例問題。

@Configuration
public class MyConfig {
    @Bean
    public MyService myService() {
        return new MyService();
    }

    public void doSomething() {
        // 通過代理,始終返回容器中的同一個(gè)實(shí)例
        MyService s1 = myService();
        MyService s2 = myService();
        System.out.println(s1 == s2); // true
    }
}

3、@Configuration 本身已經(jīng)包含了 @Component:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component // ← 注意這里!
public @interface Configuration {
    // ...
}

4、使用建議

如果你只是想把一個(gè)普通類交給 Spring 管理 → 用 @Component(或其衍生注解)。

如果你要集中定義多個(gè) Bean 的創(chuàng)建邏輯(尤其是需要復(fù)用、依賴注入、生命周期控制)→ 必須用 @Configuration。

不要在 @Component 類里寫 @Bean 方法,除非你明確知道自己在做什么(且不需要單例)。

@Component 是把一個(gè)類變成一個(gè)bean

@Configuration 是用@Bean 返回一個(gè)對(duì)象, 顯性的

@Component 是“被管理的對(duì)象”,而 @Configuration 是“管理對(duì)象的工廠”。

正確使用 @Configuration 能確保 Spring 容器對(duì) Bean 生命周期的完整控制,避免因直接方法調(diào)用導(dǎo)致的單例失效問題。

對(duì)于這個(gè) “管理對(duì)象的工廠” 的理解

1、@Configuration 本身不是工廠,而是 “工廠的藍(lán)圖”

Spring 容器(ApplicationContext)才是真正的“對(duì)象工廠”而 @Configuration 標(biāo)注的類,是 告訴這個(gè)工廠:“你要怎么生產(chǎn)某些對(duì)象” 的說明書

@Configuration // ← 這是一份“生產(chǎn)驗(yàn)證碼生成器”的配方
public class KaptchaConfig {

    @Bean(name = "captchaProducer")
    public Producer captchaProducer() {
        // 這段代碼就是“生產(chǎn)工藝”
        DefaultKaptcha kaptcha = new DefaultKaptcha();
        kaptcha.setConfig(new Config(...));
        return kaptcha; // ← 工廠按此配方生產(chǎn)出一個(gè) Bean
    }
}

2、為什么需要這種

像驗(yàn)證碼生成器(DefaultKaptcha)這類對(duì)象,不能簡(jiǎn)單通過 new 就直接使用,它需要:

  • 設(shè)置圖像寬高
  • 配置字符集、字體、干擾線等參數(shù)
  • 將這些參數(shù)封裝為 Config 對(duì)象
  • 調(diào)用 setConfig(config) 完成初始化
  • 如果每個(gè)地方都手動(dòng)寫一遍,不僅重復(fù),還難以維護(hù)。

而通過 @Configuration + @Bean,你只需 在“工廠藍(lán)圖”中定義一次,Spring 容器就會(huì)按這個(gè)配方 自動(dòng)生產(chǎn)并管理這個(gè)對(duì)象。

3、管理對(duì)象”的含義

不只是創(chuàng)建,還包括全生命周期控制

功能說明
單例管理默認(rèn)情況下,@Bean 是單例的,整個(gè)應(yīng)用只創(chuàng)建一次,節(jié)省資源
依賴注入如果你的驗(yàn)證碼生成器依賴其他 Bean(比如 Redis 緩存),Spring 會(huì)自動(dòng)注入
生命周期回調(diào)可以定義 @PostConstruct 初始化或 @PreDestroy 銷毀邏輯
AOP 支持可對(duì) Bean 進(jìn)行代理(如事務(wù)、日志、安全控制)
條件化創(chuàng)建通過 @Conditional 等注解,根據(jù)環(huán)境決定是否創(chuàng)建該對(duì)象

4、對(duì)比

沒有 @Configuration 的“野路子” vs 有 @Configuration 的“工廠模式”

場(chǎng)景手動(dòng) new(無工廠)使用 @Configuration(Spring 工廠)
創(chuàng)建方式new DefaultKaptcha() 到處寫在配置類中集中定義一次
配置修改每處都要改代碼只改 @Configuration 類或外部配置文件
多實(shí)例支持難以區(qū)分不同類型的驗(yàn)證碼通過不同 @Bean(name=...) 輕松支持
測(cè)試難以 mock 或替換可通過 Spring Test 替換 Bean
與框架集成孤立對(duì)象,無法享受 Spring 生態(tài)自動(dòng)參與事務(wù)、緩存、安全等

直接寫new DefaultKaptcha()

  • 重復(fù)初始化(每次 HTTP 請(qǐng)求都新建對(duì)象)
  • 無法統(tǒng)一管理配置
  • 不能被 Spring 管理(比如不能注入到其他 Service)

@Configuration 配置類 是替代傳統(tǒng) XML 配置的核心載體這句怎么理解

在早期 Spring(如 Spring 2.x/3.x),所有 Bean 的定義和依賴關(guān)系都寫在 XML 文件中,例如:

<!-- applicationContext.xml -->
<beans>
    <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
        <property name="config">
            <bean class="com.google.code.kaptcha.util.Config">
                <constructor-arg>
                    <props>
                        <prop key="kaptcha.image.width">200</prop>
                        <prop key="kaptcha.textproducer.char.string">0123456789</prop>
                    </props>
                </constructor-arg>
            </bean>
        </property>
    </bean>
</beans>

Spring 3.0 引入了 基于 Java 的配置(Java-based Configuration),核心就是 @Configuration + @Bean。

上面的 XML 等價(jià)于以下 Java 配置類:

@Configuration
public class KaptchaConfig {

    @Bean(name = "captchaProducer")
    public DefaultKaptcha captchaProducer() {
        Properties props = new Properties();
        props.setProperty("kaptcha.image.width", "200");
        props.setProperty("kaptcha.textproducer.char.string", "0123456789");

        Config config = new Config(props);
        DefaultKaptcha kaptcha = new DefaultKaptcha();
        kaptcha.setConfig(config);
        return kaptcha;
    }
}
維度XML 配置@Configuration 配置類
本質(zhì)外部配置文件(字符串)Java 類(強(qiáng)類型)
可讀性嵌套深、冗長(zhǎng)邏輯清晰、代碼即文檔
安全性無編譯時(shí)檢查(拼錯(cuò) key 不報(bào)錯(cuò))編譯時(shí)報(bào)錯(cuò)(方法名、類型錯(cuò)誤立刻暴露)
重構(gòu)支持IDE 難以追蹤引用支持重命名、查找引用、跳轉(zhuǎn)定義
靈活性條件邏輯需用 <profile> 等復(fù)雜標(biāo)簽直接用 if、switch、@Conditional 等 Java 邏輯
集成能力與 Java 代碼割裂可調(diào)用其他方法、使用常量、注入環(huán)境變量等

將 @Configuration 與 @ConfigurationProperties 結(jié)合使用,并綁定到 application.yml,是 Spring Boot 實(shí)現(xiàn)“外部化配置 + 類型安全注入”的核心模式

假設(shè)你想讓驗(yàn)證碼的寬度、高度、字符集等可配置,而不是硬編碼在 Java 里

# application.yml
kaptcha:
  image:
    width: 200
    height: 80
  text-producer:
    char-string: "0123456789"
    char-length: 4
// src/main/java/com/example/config/KaptchaProperties.java
package com.example.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "kaptcha")
public class KaptchaProperties {

    private Image image = new Image();
    private TextProducer textProducer = new TextProducer();

    // 嵌套類:對(duì)應(yīng) YAML 中的 kaptcha.image
    public static class Image {
        private int width = 200;
        private int height = 80;

        // Getters & Setters
        public int getWidth() { return width; }
        public void setWidth(int width) { this.width = width; }
        public int getHeight() { return height; }
        public void setHeight(int height) { this.height = height; }
    }

    // 嵌套類:對(duì)應(yīng) YAML 中的 kaptcha.text-producer
    public static class TextProducer {
        private String charString = "0123456789";
        private int charLength = 4;

        public String getCharString() { return charString; }
        public void setCharString(String charString) { this.charString = charString; }
        public int getCharLength() { return charLength; }
        public void setCharLength(int charLength) { this.charLength = charLength; }
    }

    // 外層 Getters & Setters
    public Image getImage() { return image; }
    public void setImage(Image image) { this.image = image; }
    public TextProducer getTextProducer() { return textProducer; }
    public void setTextProducer(TextProducer textProducer) { this.textProducer = textProducer; }
}
// src/main/java/com/example/config/KaptchaConfig.java
package com.example.config;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

import java.util.Properties;

@Configuration
@EnableConfigurationProperties(KaptchaProperties.class) // 啟用 KaptchaProperties
public class KaptchaConfig {

    @Bean(name = "captchaProducer")
    public DefaultKaptcha captchaProducer(KaptchaProperties props) {
        // 從 props 讀取配置
        Properties properties = new Properties();
        properties.put("kaptcha.image.width", String.valueOf(props.getImage().getWidth()));
        properties.put("kaptcha.image.height", String.valueOf(props.getImage().getHeight()));
        properties.put("kaptcha.textproducer.char.string", props.getTextProducer().getCharString());
        properties.put("kaptcha.textproducer.char.length", String.valueOf(props.getTextProducer().getCharLength()));

        // 創(chuàng)建并配置 Kaptcha
        Config config = new Config(properties);
        DefaultKaptcha kaptcha = new DefaultKaptcha();
        kaptcha.setConfig(config);

        return kaptcha;
    }
}
  • @EnableConfigurationProperties(KaptchaProperties.class):告訴 Spring “請(qǐng)加載這個(gè)配置屬性類”
  • captchaProducer(KaptchaProperties props):Spring 自動(dòng)注入已綁定好值的 KaptchaProperties 實(shí)例
  • 所有配置來自 application.yml,無需硬編碼

public class KaptchaProperties 這個(gè)類 怎么沒用yml的配置?

KaptchaProperties 這個(gè)類 本身不會(huì)自動(dòng)讀取 application.yml,它只是一個(gè)“空殼”——必須配合 SpringBoot 的機(jī)制(如 @EnableConfigurationProperties 或 @Component +@ConfigurationPropertiesScan)才能真正綁定 YAML 配置。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot實(shí)現(xiàn)快遞物流查詢功能(快遞鳥)

    SpringBoot實(shí)現(xiàn)快遞物流查詢功能(快遞鳥)

    本文將基于springboot2.4.0實(shí)現(xiàn)快遞物流查詢,物流信息的獲取通過快遞鳥第三方實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-10-10
  • Java多線程學(xué)習(xí)筆記

    Java多線程學(xué)習(xí)筆記

    常用的實(shí)現(xiàn)多線程的兩種方式:Thread和Runnable。之所以說是“常用”,是因?yàn)樵贘ava 5后可以通過java.util.concurrent包中的線程池來實(shí)現(xiàn)多線程
    2021-09-09
  • Java網(wǎng)絡(luò)編程三要素及通信程序詳解

    Java網(wǎng)絡(luò)編程三要素及通信程序詳解

    這篇文章主要介紹了Java網(wǎng)絡(luò)編程三要素及通信程序詳解,Java網(wǎng)絡(luò)編程是在網(wǎng)絡(luò)通信協(xié)議下,實(shí)現(xiàn)網(wǎng)絡(luò)互連的不同計(jì)算機(jī)上運(yùn)行的程序間可以進(jìn)行數(shù)據(jù)交換,需要的朋友可以參考下
    2023-07-07
  • Java8接口默認(rèn)靜態(tài)方法及重復(fù)注解原理解析

    Java8接口默認(rèn)靜態(tài)方法及重復(fù)注解原理解析

    這篇文章主要介紹了Java8接口默認(rèn)靜態(tài)方法及重復(fù)注解原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • java使用Memcached簡(jiǎn)單教程

    java使用Memcached簡(jiǎn)單教程

    本文主要記錄Memcached的一些基本使用和簡(jiǎn)單的Monitor,大家參考使用吧
    2013-12-12
  • synchronized底層原理之JVM層面的鎖實(shí)現(xiàn)細(xì)節(jié)與流程

    synchronized底層原理之JVM層面的鎖實(shí)現(xiàn)細(xì)節(jié)與流程

    本文從JVM底層視角,詳細(xì)拆解了synchronized的實(shí)現(xiàn)邏輯,涵蓋鎖的存儲(chǔ)載體(對(duì)象頭的MarkWord)、鎖的觸發(fā)指令(monitorenter/monitorexit指令和ACC_SYNCHRONIZED標(biāo)志位)以及鎖的調(diào)度機(jī)制,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • Java反射的應(yīng)用之動(dòng)態(tài)代理深入理解

    Java反射的應(yīng)用之動(dòng)態(tài)代理深入理解

    這篇文章主要介紹了Java反射的應(yīng)用之動(dòng)態(tài)代理深入理解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Spring中的refreshContext源碼分析

    Spring中的refreshContext源碼分析

    這篇文章主要介紹了Spring中的refreshContext源碼分析,在SpringBoot啟動(dòng)流程中,主要的兩個(gè)階段是初始化SpringApplication對(duì)象以及SpringApplication.run方法執(zhí)行的內(nèi)容,今天主要細(xì)講的是SpringApplication.run中的刷新容器refreshContext方法,需要的朋友可以參考下
    2023-12-12
  • java動(dòng)態(tài)添加外部jar包到classpath的實(shí)例詳解

    java動(dòng)態(tài)添加外部jar包到classpath的實(shí)例詳解

    這篇文章主要介紹了java動(dòng)態(tài)添加外部jar包到classpath的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • java多線程下載實(shí)例詳解

    java多線程下載實(shí)例詳解

    這篇文章主要介紹了java多線程下載,結(jié)合實(shí)例形式詳細(xì)分析了Java多線程文件傳輸?shù)脑砼c多線程下載的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-12-12

最新評(píng)論

平凉市| 定襄县| 祁阳县| 洪雅县| 肥东县| 丽江市| 秦安县| 海阳市| 赞皇县| 西城区| 汉中市| 黄石市| 乌恰县| 清河县| 苍山县| 太康县| 栖霞市| 宁乡县| 秭归县| 西丰县| 昌宁县| 安义县| 共和县| 丽水市| 北辰区| 宜黄县| 陕西省| 新乡市| 山阳县| 天峨县| 农安县| 玉林市| 宝坻区| 南靖县| 凌云县| 鲜城| 高安市| 彝良县| 牙克石市| 凤城市| 仙居县|