Spring component-scan XML配置与@ComponentScan注解配置

 更新时间:2022年09月01日 14:43:12   作者:蓝黑2020  
这篇文章主要介绍了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"/>

MyConfig2pojo 包下,所以无需额外的配置。

测试

创建测试如下:

    @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"})

MyConfig2pojo 包下,所以无需额外的配置。

测试

创建测试如下:

    @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配置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解决@Autowired注入static接口的问题

    解决@Autowired注入static接口的问题

    这篇文章主要介绍了解决@Autowired注入static接口的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • 深入讲解Java 9中的九个新特性

    深入讲解Java 9中的九个新特性

    Java 8 发布三年多之后,即将快到2017年7月下一个版本发布的日期了。 你可能已经听说过 Java 9 的模块系统,但是这个新版本还有许多其它的更新。 这里有九个令人兴奋的新功能将与 Java 9 一起发布。需要的朋友可以参考学习,下面来一起看看吧。
    2017-05-05
  • SpringBoot整合Mybatis与MybatisPlus方法详细讲解

    SpringBoot整合Mybatis与MybatisPlus方法详细讲解

    这篇文章主要介绍了SpringBoot整合Mybatis与MybatisPlus方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-01-01
  • Java观察者模式例子

    Java观察者模式例子

    这篇文章主要介绍了Java观察者模式例子的相关资料,需要的朋友可以参考下
    2015-12-12
  • Java Bean 作用域及它的几种类型介绍

    Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧
    2022-09-09
  • java split结果去除空字符串的方法实现

    java split结果去除空字符串的方法实现

    在Java开发中,我们经常需要对字符串进行分割操作,本文主要介绍了java split结果去除空字符串的方法实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • SpringBoot集成itext实现html转PDF

    SpringBoot集成itext实现html转PDF

    iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库,本文主要介绍了如何利用itext实现html转PDF,需要的可以参考下
    2024-03-03
  • Java中类的加载顺序剖析(常用于面试题)

    Java中类的加载顺序剖析(常用于面试题)

    这篇文章主要介绍了Java中类的加载顺序剖析(常用于面试题),本文直接给出代码实例和运行结果,给后给出了加载过程总结,需要的朋友可以参考下
    2015-03-03
  • 深入理解JVM自动内存管理

    深入理解JVM自动内存管理

    对于Java虚拟机在内存分配与回收的学习,本文主要介绍了JVM自动内存管理,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08
  • java处理日期的工具类DateUtil

    java处理日期的工具类DateUtil

    这篇文章主要为大家详细介绍了java处理日期的工具类DateUtil,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10

最新评论