Java-Spring入门指南(十)纯Java类配备与@Configuration实战

news/2025/9/18 8:36:16/文章来源:https://www.cnblogs.com/tlnshuju/p/19098013

Java-Spring入门指南(十)纯Java类配备与@Configuration实战

2025-09-18 08:34  tlnshuju  阅读(0)  评论(0)    收藏  举报

Java-Spring入门指南(十)纯Java类配置与@Configuration实战

  • 前言
  • 一、纯Java类配置的核心:@Configuration
    • 1.1 @Configuration的作用
    • 1.2 实战:创建第一个配置类
  • 二、手动定义@Bean
    • 2.1 基本用法
    • 2.2 测试@Bean定义的Bean
    • 2.3 自定义Bean的id
  • 三、@ComponentScan
    • 3.1 基本用法
    • 3.2 测试组件扫描
    • 3.3 @ComponentScans:组合多个扫描规则
  • 四、@Import:组合多个配置类
    • 4.1 实战:用@Import组合配置类
    • 4.2 测试@Import
  • 五、完整代码结构与测试
    • 5.1 代码结构
    • 5.2 各文件代码
      • MyConfig.java
      • MyConfig1.java
      • Student.java
      • Teacher.java
      • MyTest.java


前言

在前几篇博客中,我们从XML配置逐步过渡到注解驱动开发,掌握了@Component@Autowired等核心注解。但注解仍需依赖少量XML(如<context:component-scan>),有没有办法彻底摆脱XML,让所有配置都“写在Java类里”?

答案就是Spring的纯Java类配置(Java-based Configuration)。通过@Configuration注解,我们可以把原本写在XML里的配置(如组件扫描、Bean定义)全部转移到Java类中,让配置与业务代码更紧密地结合。

本文将聚焦@Configuration的核心用法,实战@Bean定义Bean、@ComponentScan扫描组件、@Import组合配置类,带大家体验“无XML”的Spring配置新方式。

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的Java-Spring入门指南知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_13040333.html?spm=1001.2014.3001.5482

在这里插入图片描述


一、纯Java类配置的核心:@Configuration

@Configuration是Spring纯Java配置的“入口注解”,被它标记的类会被Spring视为配置类(相当于XML配置文件),类中可以定义Bean、指定组件扫描规则等。

1.1 @Configuration的作用

1.2 实战:创建第一个配置类

我们先写一个最简单的配置类,感受它如何替代XML:

package com.niit.config;
import org.springframework.context.annotation.Configuration;
// @Configuration:标记当前类为Spring的配置类,相当于beans.xml
@Configuration
public class MyConfig
{
// 这里暂时为空,后续添加Bean定义和扫描规则
}

二、手动定义@Bean

@Bean是配置类中定义Bean的核心注解,作用相当于XML中的<bean>标签。被@Bean标记的方法,其返回值会被Spring注册为Bean,方法名默认作为Bean的id

2.1 基本用法

假设我们有一个Student类,需要将其注册为Bean:

package com.niit.pojo;
public class Student
{
private String name = "默认学生";
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}

在配置类中,用@Bean定义这个Student的Bean:

package com.niit.config;
import com.niit.pojo.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig
{
// @Bean:将方法返回的Student对象注册为Spring的Bean,id默认为方法名“getStudent”
@Bean
public Student getStudent() {
return new Student();
}
}

2.2 测试@Bean定义的Bean

通过AnnotationConfigApplicationContext加载配置类,获取Bean:

import com.niit.config.MyConfig;
import com.niit.pojo.Student;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest
{
@Test
public void testBean() {
// 加载配置类(替代ClassPathXmlApplicationContext加载XML)
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class)
;
// 获取Bean,id为方法名“getStudent”
Student student = context.getBean("getStudent", Student.class)
;
System.out.println(student);
// 输出:Student{name='默认学生'}
context.close();
}
}

2.3 自定义Bean的id

如果不想用方法名作为Bean的id,可以给@Bean指定name属性:

@Bean(name = "myStudent")
public Student getStudent() {
return new Student();
}

测试时,通过新的id获取:

在这里插入图片描述

Student student = context.getBean("myStudent", Student.class)
;

三、@ComponentScan

@ComponentScan的作用和XML中的<context:component-scan>一致,用于指定Spring要扫描的包,自动注册带有@Component@Service@Repository等注解的类为Bean。

3.1 基本用法

假设com.niit.pojo包下有一个带@Component的类:

package com.niit.pojo;
import org.springframework.stereotype.Component;
@Component
public class Teacher
{
private String name = "张老师";
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
}

在配置类中添加@ComponentScan,指定扫描com.niit.pojo包:

package com.niit.config;
import com.niit.pojo.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
// 扫描com.niit.pojo包下的组件
@ComponentScan(basePackages = {
"com.niit.pojo"
})
public class MyConfig
{
@Bean
public Student getStudent() {
return new Student();
}
}

3.2 测试组件扫描

加载配置类后,不仅能获取@Bean定义的Student,还能获取扫描到的Teacher

@Test
public void testComponentScan() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class)
;
// 获取@Bean定义的Student
Student student = context.getBean("getStudent", Student.class)
;
System.out.println(student);
// 获取扫描到的Teacher(id为类名首字母小写“teacher”)
Teacher teacher = context.getBean("teacher", Teacher.class)
;
System.out.println(teacher);
// 输出:Teacher{name='张老师'}
context.close();
}

3.3 @ComponentScans:组合多个扫描规则

如果需要同时扫描多个包或配置复杂的扫描规则,可以用@ComponentScans组合多个@ComponentScan

@Configuration
@ComponentScans({
@ComponentScan(basePackages = "com.niit.pojo"),
@ComponentScan(basePackages = "com.niit.service")
})
public class MyConfig
{
// ...
}

四、@Import:组合多个配置类

当配置类较多时,可通过@Import将多个配置类合并,统一加载。

4.1 实战:用@Import组合配置类

假设有两个配置类MyConfigMyConfig1

// MyConfig.java
package com.niit.config;
import com.niit.pojo.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {
"com.niit.pojo"
})
public class MyConfig
{
@Bean
public Student getStudent() {
return new Student();
}
}
// MyConfig1.java
package com.niit.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(MyConfig.class)
// 导入MyConfig配置类
public class MyConfig1
{
// 可添加自己的Bean定义或扫描规则
}

4.2 测试@Import

只需加载MyConfig1,即可同时包含MyConfig的配置:

@Test
public void testImport() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig1.class)
;
// 能获取MyConfig中定义的Student
Student student = context.getBean("getStudent", Student.class)
;
System.out.println(student);
// 能获取MyConfig扫描到的Teacher
Teacher teacher = context.getBean("teacher", Teacher.class)
;
System.out.println(teacher);
context.close();
}

五、完整代码结构与测试

5.1 代码结构

com.niit
├─ config
│  ├─ MyConfig.java
│  └─ MyConfig1.java
├─ pojo
│  ├─ Student.java
│  └─ Teacher.java
└─ test
└─ MyTest.java

5.2 各文件代码

MyConfig.java

package com.niit.config;
import com.niit.pojo.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {
"com.niit.pojo"
})
public class MyConfig
{
@Bean
public Student getStudent() {
return new Student();
}
}

MyConfig1.java

package com.niit.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(MyConfig.class)
public class MyConfig1
{
}

Student.java

package com.niit.pojo;
public class Student
{
private String name = "默认学生";
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}

Teacher.java

package com.niit.pojo;
import org.springframework.stereotype.Component;
@Component
public class Teacher
{
private String name = "张老师";
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
}

MyTest.java

import com.niit.config.MyConfig;
import com.niit.config.MyConfig1;
import com.niit.pojo.Student;
import com.niit.pojo.Teacher;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest
{
@Test
public void test() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class)
;
Student student = context.getBean("getStudent", Student.class)
;
System.out.println(student);
Teacher teacher = context.getBean("teacher", Teacher.class)
;
System.out.println(teacher);
context.close();
}
@Test
public void testImport() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig1.class)
;
Student student = context.getBean("getStudent", Student.class)
;
System.out.println(student);
Teacher teacher = context.getBean("teacher", Teacher.class)
;
System.out.println(teacher);
context.close();
}
}

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的Java-Spring入门指南知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_13040333.html?spm=1001.2014.3001.5482

非常感谢您的阅读,喜欢的话记得三连哦

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

院士增选有效候选人公示材料都有什么内容?

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 35469554100490872025年科学院和工程院增选有效候选人材料公示好多天了,本来想好好…

可视化大屏素材展示系统 拖拽生成各种炫酷的大屏(源码下载)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

GPU微架构与多线程架构深入解析

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087 摘要本文深入探讨GPU微架构的核心概念,重点分析多线程架构、存储…

完整教程:基于RSim的自动驾驶高保真仿真场景实现方案

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

完整教程:C2(Command Control)命令与控制

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

TechInsights 拆解:蔚来“亚当(Adam)”超级计算机

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087 添加图片注释,不超过 140 字(可选)蔚来亚当超级计算机是蔚来电…

拼接

叠甲:作者本人没有 npy,故事纯虚构。谢谢你的陪伴呢!你真的是一个出色的人!纵使天空不作美 就算阴雨连绵 还是一同展翅高飞把 云层上定是晴空万里 还是一同启航前往明天吧 明天定会比今天更好 我想自己会选择 永不…

用户只需要知道「怎么办」,不需要知道「为什么炸了」

大家好,我是晓凡。 写在前面 一到月初或者月末(某些业务操作大规模爆发的时候),手机狂震,生产告警狂轰滥炸:xxx接口超时、用户中心 CPU 飙到 98%…… 运维在群里疯狂 @ 你,你却只能回一句“我本地是好的”。 别…

2025数学院士增选背后的争议:海外光环与本土贡献的考量

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087自从2025年中国科学院数学物理学部院士增选有效候选人名单公布以来…

一根网线搞定远程运维,GL-RM1PE 深度体验:远程运维、装机、开机一体化的 KVM over IP - 详解

一根网线搞定远程运维,GL-RM1PE 深度体验:远程运维、装机、开机一体化的 KVM over IP - 详解2025-09-18 08:13 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !impo…

完整教程:建筑物裂缝、钢筋裸漏、建筑物墙面脱落图像数据集

完整教程:建筑物裂缝、钢筋裸漏、建筑物墙面脱落图像数据集pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Conso…

深入剖析布谷网剧短剧app系统软件源码之技术

随着短视频和网剧市场的迅猛发展,企业和内容创作者对专业、高效的短剧平台需求日益增长。山东布谷鸟网络科技有限公司凭借丰富的软件开发经验,推出了布谷短剧app源码、网剧系统源码及短剧软件搭建服务,致力于为客户…

在AI技术快速实现功能的时代,挖掘电子书阅读器新需求成为关键突破点

随着AI技术让功能实现变得前所未有的简单,真正的挑战转向了如何发现和满足用户未被满足的需求。本文通过分析某知名跨平台电子书阅读器的用户反馈,揭示了阅读体验优化、格式兼容性、安全增强等关键需求领域。内容描述…

jtag协议处理流程 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

PHP 如何利用 Opcache 来实现保护源码

PHP 如何利用 Opcache 来实现保护源码感兴趣得可以试试看!!!要求不用 IonCube(或类似的)。不知道这是啥的话,就是加密 PHP 代码但还能运行的工具。问题是太贵了。😅 性能要好,PHP 原生支持。原文链接 PHP 如何…

cocoindex 面向ai 的数据转换框架

cocoindex 面向ai 的数据转换框架cocoindex 面向ai 的数据转换框架基于rust开发,提供了python sdk,提供了基于data flow 的数据开发模式,支持增量数据更新 支持embedding 方便构建知识库,同时提供了超越sql 的数据…

给RAG打分:小白也能懂的AI系统评测全攻略

RAG系统评估听起来高深,其实跟我们生活中的尝鲜评测没啥两样!本文用轻松幽默的方式,带你从检索质量、生成质量到用户体验,全方位掌握如何科学评测RAG系统,避免踩坑,让你的AI应用又快又准。#RAG技术 #AI评估 #信息…

WComputer2027广义计算器下载広義の計算機ダウンロードGeneralized calculator download

WComputer2027广义计算器下载広義の計算機ダウンロードGeneralized calculator download2025-09-18 07:47 软件商 阅读(0) 评论(0) 收藏 举报功能强大的多功能数学物理计算器 Powerful multifunctional mathematic…

P8114 [Cnoi2021] 六边形战士

传送 非常好玩的题! 首先你大概率看过一些“无字证明”,其中很经典的是这个: 证明:用若干个边长为 \(1\),顶角为 \(60\) 度的菱形拼成一个边长为 \(n\) 的正六边形,三个方向的菱形个数一定相等。这是一个经典的无…

【GitHub每日速递 250918】开发者必藏!336k 星标项目告诉你:前端 / 后端 / AI 岗该怎么学才高效

原文:https://mp.weixin.qq.com/s/Oo5T6g68BNe9QUTL4bHrIg AI外语学习神器Enjoy上线!网页版、桌面版全攻略来袭 everyone-can-use-english 是一个帮助用户学习和使用英语的工具类应用。简单讲,它通过技术手段降低英…