Spring中如何通过XML和@ComponentScan注解实现组件扫描配置?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1791个文字,预计阅读时间需要8分钟。
目录+前言+准备+@Component的bean XML配置+Java配置+配置+@Configuration的bean XML配置+Java配置+配置+小结+总结+关于SpringBoot+前言+无需手动配置Spring的XML或Java配置,均可自动扫描配置+
目录
- 前言
- 准备
- @Component的bean
- XML配置
- Java配置 配置
- @Configuration的bean
- XML配置 配置
- Java配置 配置
- 小结
- 总结
- 关于SpringBoot
前言
无论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 文件,添加依赖:
...... <!-- mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <!-- 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="www.springframework.org/schema/beans" xmlns:xsi="www.w3.org/2001/XMLSchema-instance" xmlns:context="www.springframework.org/schema/context" xsi:schemaLocation="www.springframework.org/schema/beans www.springframework.org/schema/beans/spring-beans.xsd www.springframework.org/schema/context 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
前面已经配置了:
@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配置,详见我另一篇文档 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配置内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!
本文共计1791个文字,预计阅读时间需要8分钟。
目录+前言+准备+@Component的bean XML配置+Java配置+配置+@Configuration的bean XML配置+Java配置+配置+小结+总结+关于SpringBoot+前言+无需手动配置Spring的XML或Java配置,均可自动扫描配置+
目录
- 前言
- 准备
- @Component的bean
- XML配置
- Java配置 配置
- @Configuration的bean
- XML配置 配置
- Java配置 配置
- 小结
- 总结
- 关于SpringBoot
前言
无论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 文件,添加依赖:
...... <!-- mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <!-- 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="www.springframework.org/schema/beans" xmlns:xsi="www.w3.org/2001/XMLSchema-instance" xmlns:context="www.springframework.org/schema/context" xsi:schemaLocation="www.springframework.org/schema/beans www.springframework.org/schema/beans/spring-beans.xsd www.springframework.org/schema/context 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
前面已经配置了:
@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配置,详见我另一篇文档 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配置内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

