純Java類配置與@Configuration實(shí)戰(zhàn)指南
前言
在前幾篇博客中,我們從XML配置逐步過渡到注解驅(qū)動(dòng)開發(fā),掌握了@Component、@Autowired等核心注解。但注解仍需依賴少量XML(如<context:component-scan>),有沒有辦法徹底擺脫XML,讓所有配置都“寫在Java類里”?
答案就是Spring的純Java類配置(Java-based Configuration)。通過@Configuration注解,我們可以把原本寫在XML里的配置(如組件掃描、Bean定義)全部轉(zhuǎn)移到Java類中,讓配置與業(yè)務(wù)代碼更緊密地結(jié)合。
本文將聚焦@Configuration的核心用法,實(shí)戰(zhàn)@Bean定義Bean、@ComponentScan掃描組件、@Import組合配置類,帶大家體驗(yàn)“無XML”的Spring配置新方式。
一、純Java類配置的核心:@Configuration
@Configuration是Spring純Java配置的“入口注解”,被它標(biāo)記的類會(huì)被Spring視為配置類(相當(dāng)于XML配置文件),類中可以定義Bean、指定組件掃描規(guī)則等。
1.1 @Configuration的作用
- 替代XML配置文件,讓配置“代碼化”;
- 配置類本身也會(huì)被Spring管理,作為一個(gè)Bean存在于容器中;
- 支持通過
@Bean、@ComponentScan等注解,在類中完成所有Spring配置。
1.2 實(shí)戰(zhàn):創(chuàng)建第一個(gè)配置類
我們先寫一個(gè)最簡(jiǎn)單的配置類,感受它如何替代XML:
package com.niit.config;
import org.springframework.context.annotation.Configuration;
// @Configuration:標(biāo)記當(dāng)前類為Spring的配置類,相當(dāng)于beans.xml
@Configuration
public class MyConfig
{
// 這里暫時(shí)為空,后續(xù)添加Bean定義和掃描規(guī)則
}二、手動(dòng)定義@Bean
@Bean是配置類中定義Bean的核心注解,作用相當(dāng)于XML中的<bean>標(biāo)簽。被@Bean標(biāo)記的方法,其返回值會(huì)被Spring注冊(cè)為Bean,方法名默認(rèn)作為Bean的id。
2.1 基本用法
假設(shè)我們有一個(gè)Student類,需要將其注冊(cè)為Bean:
package com.niit.pojo;
public class Student
{
private String name = "默認(rèn)學(xué)生";
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}在配置類中,用@Bean定義這個(gè)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對(duì)象注冊(cè)為Spring的Bean,id默認(rèn)為方法名“getStudent”
@Bean
public Student getStudent() {
return new Student();
}
}2.2 測(cè)試@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='默認(rèn)學(xué)生'}
context.close();
}
}2.3 自定義Bean的id
如果不想用方法名作為Bean的id,可以給@Bean指定name屬性:
@Bean(name = "myStudent")
public Student getStudent() {
return new Student();
}測(cè)試時(shí),通過新的id獲?。?/p>

Student student = context.getBean("myStudent", Student.class)
;三、@ComponentScan
@ComponentScan的作用和XML中的<context:component-scan>一致,用于指定Spring要掃描的包,自動(dòng)注冊(cè)帶有@Component、@Service、@Repository等注解的類為Bean。
3.1 基本用法
假設(shè)com.niit.pojo包下有一個(gè)帶@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 測(cè)試組件掃描
加載配置類后,不僅能獲取@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:組合多個(gè)掃描規(guī)則
如果需要同時(shí)掃描多個(gè)包或配置復(fù)雜的掃描規(guī)則,可以用@ComponentScans組合多個(gè)@ComponentScan:
@Configuration
@ComponentScans({
@ComponentScan(basePackages = "com.niit.pojo"),
@ComponentScan(basePackages = "com.niit.service")
})
public class MyConfig
{
// ...
}四、@Import:組合多個(gè)配置類
當(dāng)配置類較多時(shí),可通過@Import將多個(gè)配置類合并,統(tǒng)一加載。
4.1 實(shí)戰(zhàn):用@Import組合配置類
假設(shè)有兩個(gè)配置類MyConfig和MyConfig1:
// 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)
// 導(dǎo)入MyConfig配置類
public class MyConfig1
{
// 可添加自己的Bean定義或掃描規(guī)則
}4.2 測(cè)試@Import
只需加載MyConfig1,即可同時(shí)包含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();
}五、完整代碼結(jié)構(gòu)與測(cè)試
5.1 代碼結(jié)構(gòu)
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 = "默認(rèn)學(xué)生";
@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();
}
}到此這篇關(guān)于純Java類配備與@Configuration實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)純Java類配備與@Configuration實(shí)戰(zhàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中幾種常用數(shù)據(jù)庫(kù)連接池的使用
數(shù)據(jù)庫(kù)連接池在編寫應(yīng)用服務(wù)是經(jīng)常需要用到的模塊,太過頻繁的連接數(shù)據(jù)庫(kù)對(duì)服務(wù)性能來講是一個(gè)瓶頸,使用緩沖池技術(shù)可以來消除這個(gè)瓶頸,本文就來介紹Java常見的幾種,感興趣的可以了解一下2021-05-05
Java實(shí)現(xiàn)Executors類創(chuàng)建常見線程池
本文主要介紹了Java實(shí)現(xiàn)Executors類創(chuàng)建常見線程池,在Java中,可以通過Executors工廠類提供四種常見類型的線程池,下面就來介紹一下這四種的方法實(shí)現(xiàn),感興趣的可以了解一下2023-11-11
SpringCloud2020版本配置與環(huán)境搭建教程詳解
這篇文章主要介紹了SpringCloud2020版本配置與環(huán)境搭建教程詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
spring security登錄成功后通過Principal獲取名返回空問題
這篇文章主要介紹了spring security登錄成功后通過Principal獲取名返回空問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
Spring,hibernate,struts經(jīng)典面試筆試題(含答案)
這篇文章主要介紹了Spring,hibernate,struts經(jīng)典面試筆試題極其參考含答案,涉及SSH基本概念,原理與使用技巧,需要的朋友可以參考下2016-03-03
如何把本地idea上的項(xiàng)目上傳到github上(推薦)
這篇文章主要介紹了如何把本地idea上的項(xiàng)目上傳到github上,本文通過圖文的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07

