这篇文章主要介绍了Spring component-scan XML配置与@ComponentScan注解配置,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
前言
无论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})
总结
- 在类上添加
@Component
(或者其变种)注解。 - 配置自动扫描,以下两种方式都可以:
XML配置:
<context:component-scan base-package="pojo"/>
Java配置:
@Configuration
@ComponentScan(basePackages = {"pojo"})
public class MyConfig {
}
对于自动扫描路径里面的Java配置类( @Configuration
注解所修饰的类),也会被加载生效。
注:关于Spring的XML配置和Java配置,详见我另一篇文档 https://blog.csdn.net/duke_ding2/article/details/125605817
。
关于SpringBoot
SpringBoot的入口程序一般如下:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
即,调用 SpringApplication.run()
方法来启动程序,第一个参数是一个类,该类需要被 @SpringBootApplication
注解所修饰。
@SpringBootApplication
该注解包含了以下3个注解:
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
也就是说, @SpringBootApplication
包含了上面提到的Java配置的两个注解 @Configuration
和 @ComponentScan
。
换句话说, @SpringBootApplication
所修饰的类就是程序的主配置类。
有一点需要注意的是,在默认情况下(没有指定包扫描路径),会自动扫描主配置类所在的包(及其子包)。因此,该包及子包下的组件类和配置类都会被扫描。
当然也可以显式指定包扫描路径,需要注意的是,其属性名是 scanBasePakcages
,而不是 basePackages
。
对比下面两个注解:
- @ComponentScan(basePackages = "com.example.demo.pojo")
- @SpringBootApplication(scanBasePackages = "com.example.demo.pojo")
若显式指定了包扫描路径,则会覆盖默认设置(主配置类所在的包及子包不会被扫描)。
到此这篇关于Spring component-scan XML配置与@ComponentScan注解配置的文章就介绍到这了,更多相关Spring XML配置内容请搜索编程学习网以前的文章希望大家以后多多支持编程学习网!
本文标题为:Spring component-scan XML配置与@ComponentScan注解配置
基础教程推荐
- java基础知识之FileInputStream流的使用 2023-08-11
- Java数据结构之对象比较详解 2023-03-07
- Java实现查找文件和替换文件内容 2023-04-06
- ConditionalOnProperty配置swagger不生效问题及解决 2023-01-02
- Java文件管理操作的知识点整理 2023-05-19
- java实现多人聊天系统 2023-05-19
- springboot自定义starter方法及注解实例 2023-03-31
- Java并发编程进阶之线程控制篇 2023-03-07
- Java实现线程插队的示例代码 2022-09-03
- JDK数组阻塞队列源码深入分析总结 2023-04-18