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

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

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

SpringBoot配置類注解@Configuration, @Bean

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

標(biāo)識一個類為 配置類(替代傳統(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); // ← 必須手動調(diào)用
        return kaptcha;
    }
}
@RestController
public class CaptchaController
{
    @Resource(name = "captchaProducer")
    private Producer captchaProducer;

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

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

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

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

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

1、定位不同

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

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

2、對 @Bean 方法的處理方式不同(關(guān)鍵區(qū)別?。?/h3>
  • @Configuration 類中的 @Bean 方法:

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

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

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

  • @Component 類中的 @Bean 方法:

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

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

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

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

    public void doSomething() {
        // 通過代理,始終返回容器中的同一個實例
        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、使用建議

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

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

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

@Component 是把一個類變成一個bean

@Configuration 是用@Bean 返回一個對象, 顯性的

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

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

對于這個 “管理對象的工廠” 的理解

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

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

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

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

2、為什么需要這種

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

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

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

3、管理對象”的含義

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

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

4、對比

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

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

直接寫new DefaultKaptcha()

  • 重復(fù)初始化(每次 HTTP 請求都新建對象)
  • 無法統(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 等價于以下 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)類型)
可讀性嵌套深、冗長邏輯清晰、代碼即文檔
安全性無編譯時檢查(拼錯 key 不報錯)編譯時報錯(方法名、類型錯誤立刻暴露)
重構(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 實現(xiàn)“外部化配置 + 類型安全注入”的核心模式

假設(shè)你想讓驗證碼的寬度、高度、字符集等可配置,而不是硬編碼在 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();

    // 嵌套類:對應(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; }
    }

    // 嵌套類:對應(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 “請加載這個配置屬性類”
  • captchaProducer(KaptchaProperties props):Spring 自動注入已綁定好值的 KaptchaProperties 實例
  • 所有配置來自 application.yml,無需硬編碼

public class KaptchaProperties 這個類 怎么沒用yml的配置?

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

總結(jié)

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

相關(guān)文章

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

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

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

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

    常用的實現(xiàn)多線程的兩種方式:Thread和Runnable。之所以說是“常用”,是因為在Java 5后可以通過java.util.concurrent包中的線程池來實現(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é)議下,實現(xiàn)網(wǎng)絡(luò)互連的不同計算機(jī)上運行的程序間可以進(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ì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • java使用Memcached簡單教程

    java使用Memcached簡單教程

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

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

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

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

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

    Spring中的refreshContext源碼分析

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

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

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

    java多線程下載實例詳解

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

最新評論

菏泽市| 合江县| 苗栗市| 故城县| 太湖县| 明星| 邓州市| 渝中区| 义马市| 漳州市| 安塞县| 乌海市| 淮滨县| 吉安县| 中方县| 洪湖市| 宜丰县| 浑源县| 棋牌| 明星| 郸城县| 玛沁县| 海城市| 马山县| 邯郸县| 峡江县| 介休市| 屯门区| 南丰县| 阳东县| 嘉峪关市| 当阳市| 定州市| 阿拉善盟| 繁峙县| 辉南县| 南昌县| 乐昌市| 普宁市| 武城县| 海阳市|