Spring?component-scan?XML配置與@ComponentScan注解配置
前言
無論Spring的XML配置或者Java配置,都可以配置自動掃描,也就是在指定包及其子包下的component,都會被自動掃描并被Spring容器管理。
注:component指的是被 @Component 注解及其變種(如 @Controller 、 @Service 、 @Repository 、 @Configuration 等)所修飾的類。
環(huán)境:
- Ubuntu 22.04
- IntelliJ IDEA 2022.1.3
- JDK 17.0.3
- Spring 5.3.21
準(zhǔn)備
創(chuàng)建Maven項目 test0831 。
修改 pom.xml 文件,添加依賴:
......
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.21</version>
</dependency>
......在 src/test/java 目錄下創(chuàng)建測試:
public class MyTest {}
創(chuàng)建如下POJO:
Axe:Axe接口;StoneAxe:Axe實現(xiàn)類;SteelAxe:Axe實現(xiàn)類;Person:Person持有Axe
package pojo;
public interface Axe {
public void chop();
}package pojo;
import org.springframework.stereotype.Component;
@Component
public class StoneAxe implements Axe{
@Override
public void chop() {
System.out.println("Stone axe!");
}
}package pojo;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Primary
public class SteelAxe implements Axe{
@Override
public void chop() {
System.out.println("Steel axe!");
}
}
package pojo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Person {
private String name;
private Axe axe;
public void setAxe(Axe axe) {
this.axe = axe;
}
public void setName(String name) {
this.name = name;
}
public void useAxe() {
System.out.println("I am " + name);
axe.chop();
}
@Autowired
public Person(@Value("Tom") String name, Axe axe) {
this.name = name;
this.axe = axe;
}
}注:本例使用了 @Autowired 注解來自動裝配注入,默認(rèn)是 byType ,當(dāng)有多個類都滿足條件時Spring會報錯,所以使用了 @Primary 注解來指定優(yōu)先選擇該類。
@Component的bean
XML配置
配置:
在 src/main/resources 目錄下創(chuàng)建 applicationContext.xml 文件:
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="pojo"/>
</beans>測試:
創(chuàng)建測試如下:
@Test
public void test1() {
var ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
var person = ctx.getBean("person", Person.class);
person.useAxe();
}運(yùn)行測試,結(jié)果如下:
I am Tom
Steel axe!
Java配置 配置
創(chuàng)建Java配置類 MyConfig.java 如下:
package config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {"pojo"})
public class MyConfig {
}測試:
創(chuàng)建測試如下:
@Test
public void test2() {
var ctx = new AnnotationConfigApplicationContext(MyConfig.class);
var person = ctx.getBean("person", Person.class);
person.useAxe();
}運(yùn)行測試,結(jié)果如下:
I am Tom
Steel axe!
@Configuration的bean
自動掃描時,如果遇到Java配置類,也會加載其配置。
在 pojo 包下添加Java配置類 MyConfig2 :
package pojo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig2 {
@Bean
public String xxx() {
return "xxx";
}
}本例中, MyConfig2 是一個配置類,其中配置了ID為 xxx 的bean。
XML配置 配置
前面已經(jīng)配置了:
<context:component-scan base-package="pojo"/>
MyConfig2 在 pojo 包下,所以無需額外的配置。
測試
創(chuàng)建測試如下:
@Test
public void test3() {
var ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
var xxx = ctx.getBean("xxx", String.class);
System.out.println(xxx);
}運(yùn)行測試,結(jié)果如下:
xxx
Java配置 配置
前面已經(jīng)配置了:
@ComponentScan(basePackages = {"pojo"})MyConfig2 在 pojo 包下,所以無需額外的配置。
測試
創(chuàng)建測試如下:
@Test
public void test4() {
var ctx = new AnnotationConfigApplicationContext(MyConfig.class);
var xxx = ctx.getBean("xxx", String.class);
System.out.println(xxx);
}運(yùn)行測試,結(jié)果如下:
xxx
小結(jié)
@Configuration 是 @Component 的變種,因此也會被自動掃描并加載。
如果Java配置類不是在自動掃描的路徑里,則需要顯式加載:
通過XML配置加載:
<context:annotation-config/> <bean class="config.MyConfig3"/>
通過Java配置加載:
@Import({MyConfig3.class})總結(jié)
- 在類上添加
@Component(或者其變種)注解。 - 配置自動掃描,以下兩種方式都可以:
XML配置:
<context:component-scan base-package="pojo"/>
Java配置:
@Configuration
@ComponentScan(basePackages = {"pojo"})
public class MyConfig {
}對于自動掃描路徑里面的Java配置類( @Configuration 注解所修飾的類),也會被加載生效。
注:關(guān)于Spring的XML配置和Java配置,詳見我另一篇文檔 https://blog.csdn.net/duke_ding2/article/details/125605817 。
關(guān)于SpringBoot
SpringBoot的入口程序一般如下:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}即,調(diào)用 SpringApplication.run() 方法來啟動程序,第一個參數(shù)是一個類,該類需要被 @SpringBootApplication 注解所修飾。
@SpringBootApplication 該注解包含了以下3個注解:
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
也就是說, @SpringBootApplication 包含了上面提到的Java配置的兩個注解 @Configuration
和 @ComponentScan 。
換句話說, @SpringBootApplication 所修飾的類就是程序的主配置類。
有一點需要注意的是,在默認(rèn)情況下(沒有指定包掃描路徑),會自動掃描主配置類所在的包(及其子包)。因此,該包及子包下的組件類和配置類都會被掃描。
當(dāng)然也可以顯式指定包掃描路徑,需要注意的是,其屬性名是 scanBasePakcages ,而不是 basePackages 。
對比下面兩個注解:
- @ComponentScan(basePackages = "com.example.demo.pojo")
- @SpringBootApplication(scanBasePackages = "com.example.demo.pojo")
若顯式指定了包掃描路徑,則會覆蓋默認(rèn)設(shè)置(主配置類所在的包及子包不會被掃描)。
到此這篇關(guān)于Spring component-scan XML配置與@ComponentScan注解配置的文章就介紹到這了,更多相關(guān)Spring XML配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java并發(fā)Map面試線程安全數(shù)據(jù)結(jié)構(gòu)全面分析
本文將探討如何在Java中有效地應(yīng)對這些挑戰(zhàn),介紹一種強(qiáng)大的工具并發(fā)Map,它能夠幫助您管理多線程環(huán)境下的共享數(shù)據(jù),確保數(shù)據(jù)的一致性和高性能,深入了解Java中的并發(fā)Map實現(xiàn),包括ConcurrentHashMap和ConcurrentSkipListMap,及相關(guān)知識點2023-09-09
Java編寫時間工具類ZTDateTimeUtil的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用Java編寫時間工具類ZTDateTimeUtil,文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-11-11
強(qiáng)烈推薦MyBatis?三種批量插入方式的比較
這篇文章主要介紹了強(qiáng)烈推薦MyBatis?三種批量插入方式的比較,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-07-07
ScheduledThreadPoolExecutor巨坑解決
這篇文章主要為大家介紹了使用ScheduledThreadPoolExecutor遇到的巨坑解決示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
Java實現(xiàn)數(shù)據(jù)更新和事件通知的觀察者模式
Java觀察者模式是一種行為型設(shè)計模式,用于實現(xiàn)對象間的一對多依賴關(guān)系。當(dāng)一個對象的狀態(tài)發(fā)生改變時,它的所有依賴對象都會收到通知并自動更新。觀察者模式可以實現(xiàn)松耦合,增強(qiáng)了系統(tǒng)的可維護(hù)性和可拓展性2023-04-04

