Spring component-scan XML配置与@ComponentScan注解配置
作者:蓝黑2020 时间:2023-07-04 03:37:12
前言
无论Spring的XML配置或者Java配置,都可以配置自动扫描,也就是在指定包及其子包下的component,都会被自动扫描并被Spring容器管理。
注:component指的是被 @Component
注解及其变种(如 @Controller
、 @Service
、 @Repository
、 @Configuration
等)所修饰的类。
环境:
Ubuntu 22.04
IntelliJ IDEA 2022.1.3
JDK 17.0.3
Spring 5.3.21
准备
创建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
目录下创建测试:
public class MyTest {}
创建如下POJO:
Axe
:Axe接口;StoneAxe
:Axe实现类;SteelAxe
:Axe实现类;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
注解来自动装配注入,默认是 byType
,当有多个类都满足条件时Spring会报错,所以使用了 @Primary
注解来指定优先选择该类。
@Component的bean
XML配置
配置:
在 src/main/resources
目录下创建 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>
测试:
创建测试如下:
@Test
public void test1() {
var ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
var person = ctx.getBean("person", Person.class);
person.useAxe();
}
运行测试,结果如下:
I am Tom
Steel axe!
Java配置 配置
创建Java配置类 MyConfig.java
如下:
package config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {"pojo"})
public class MyConfig {
}
测试:
创建测试如下:
@Test
public void test2() {
var ctx = new AnnotationConfigApplicationContext(MyConfig.class);
var person = ctx.getBean("person", Person.class);
person.useAxe();
}
运行测试,结果如下:
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配置 配置
前面已经配置了:
<context:component-scan base-package="pojo"/>
MyConfig2
在 pojo
包下,所以无需额外的配置。
测试
创建测试如下:
@Test
public void test3() {
var ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
var xxx = ctx.getBean("xxx", String.class);
System.out.println(xxx);
}
运行测试,结果如下:
xxx
Java配置 配置
前面已经配置了:
@ComponentScan(basePackages = {"pojo"})
MyConfig2
在 pojo
包下,所以无需额外的配置。
测试
创建测试如下:
@Test
public void test4() {
var ctx = new AnnotationConfigApplicationContext(MyConfig.class);
var xxx = ctx.getBean("xxx", String.class);
System.out.println(xxx);
}
运行测试,结果如下:
xxx
小结
@Configuration
是 @Component
的变种,因此也会被自动扫描并加载。
如果Java配置类不是在自动扫描的路径里,则需要显式加载:
通过XML配置加载:
<context:annotation-config/>
<bean class="config.MyConfig3"/>
通过Java配置加载:
@Import({MyConfig3.class})
来源:https://blog.csdn.net/duke_ding2/article/details/126617024