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

目录
  • 前言
  • 准备
  • @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 文件,添加依赖:

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

(0)

相关推荐

  • 基于@ComponentScan注解的使用详解

    目录 @ComponentScan注解的使用 一.注解定义 二.使用 1.环境准备 2.excludeFilters的使用 3.includeFilters的使用 4.自定义过滤规则 关于@ComponentScan注解的一些细节 @ComponentScan注解的使用 一.注解定义 @ComponentScan注解的定义如下: @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Repeatabl

  • springboot @ComponentScan注解原理解析

    这篇文章主要介绍了springboot @ComponentScan注解原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 @ComponentScan 告诉Spring从哪里找到bean. 如果你的其他包都在@SpringBootApplication注解的启动类所在的包及其下级包,则你什么都不用做,SpringBoot会自动帮你把其他包都扫描了. 如果你有一些bean所在的包,不在启动类的包及其下级包,那么你需要手动加上@Compone

  • spring boot自动装配之@ComponentScan注解用法详解

    目录 1.@ComponentScan注解作用 2. @ComponentScan注解属性 3. @ComponentScan过滤规则说明 4. 自定义扫描过滤规则 5. @ComponentScans 6. spring boot处理@ComponentScan源码分析 总结 1.@ComponentScan注解作用 @ComponentScan用于类或接口上主要是指定扫描路径,spring会把指定路径下带有指定注解的类自动装配到bean容器里.会被自动装配的注解包括@Controller.@

  • Spring注解开发@Bean和@ComponentScan使用案例

    组件注册 用@Bean来注册 搭建好maven web工程 pom加入spring-context,spring-core等核心依赖 创建实例类com.hjj.bean.Person, 生成getter,setter方法 public class Person { private String name; private int age; } 创建com.hjj.config.MainConfig @Configuration //告诉spring是一个配置类 public class Main

  • @ComponentScan注解用法之包路径占位符解析

    目录 代码测试 底层行为分析 总结 @ComponentScan注解的basePackages属性支持占位符吗? 答案是肯定的. 代码测试 首先编写一个属性配置文件(Properties),名字随意,放在resources目录下. 在该文件中只需要定义一个属性就可以,属性名随意,值必须是要扫描的包路径. basepackages=com.xxx.fame.placeholder 编写一个Bean,空类即可. package com.xxx.fame.placeholder; import org

  • 详解spring 配置的两种方式:JAVA配置和注解配置

    众所周知,spring自从3.0开始以后,就全面推荐使用配置的方式进行代码编写了,这种方式确实可以避免了之前一个项目里面一大堆XML的情况,毕竟XML的可读性实在不怎么样,而且一会写JAVA,一会写XML,确实还是蛮麻烦的 就目前来说spring的配置方式一般为两种:JAVA配置和注解配置.那么什么的是注解配置呢?什么是JAVA配置呢? //注解配置: @Service @Component @Repository @Controlle //JAVA配置 @Confirguration 相当于s

  • Java之Spring注解配置bean实例代码解析

    前面几篇均是使用xml配置bean,如果有上百个bean,这是不可想象的.故而,请使用注解配置bean !!! [1]注解类别 @Component : 基本注解, 标识了一个受 Spring(点击这里可以下载<Spring应用开发完全手册>) 管理的组件 @Repository : 标识持久层组件 @Service : 标识服务层(业务层)组件 @Controller : 标识表现层组件 Spring 能够从 classpath 下自动扫描, 侦测和实例化具有特定注解的组件. 对于扫描到的组

  • 利用注解配置Spring容器的方法

    本文介绍了利用注解配置Spring容器的方法,分享给大家,具体如下: @Configuration标注在类上,相当于将该类作为spring的xml的标签 @Configuration public class SpringConfiguration { public SpringConfiguration() { System.out.println("初始化Spring容器"); } } 主函数进行测试 public class Main { public static void m

  • Spring注解配置AOP导致通知执行顺序紊乱解决方案

    今天在测试Spring的AOP时,发现使用注解配置AOP的方式会导致通知的执行顺序紊乱.[最终通知居然在异常通知之前执行了] 测试代码 (1)定义TargetInterface目标接口 public interface TargetInterface { public abstract void targetProxy(); } (2)定义TargetImpl目标类 @Component("target") public class TargetImpl implements Targ

  • Spring注解配置IOC,DI的方法详解

    目录 1.注解 @Component 第一步:在 applicationContext.xml 中引入命名空间 第二步:在 applicationContext.xml 文件中引入注解扫描器 第三步:在 Person 类中添加注解@Component 第四步:测试 2.@Repository @Service @Controller 3.注解@Resource 4.注解 @Autowired 第一步:创建接口 PersonDao 第二步:创建一个接口实现类 PersonDaoImplOne 第三

  • 详解Spring MVC4 纯注解配置教程

    阅读本文需要又一定的sping基础,最起码要成功的运行过一个SpringMvc项目. 在传统的Spring项目中,我们要写一堆的XML文件.而这些XML文件格式要求又很严格,很不便于开发.而网上所谓的0配置,并不是纯粹的0配置,还是要写一些xml配置,只是用了几个@Service,@Controller注解而已. 在这里,我讲介绍一种新的配置方式,一行XML代码都不需要,什么web.xml,Application-context.xml,Beans.xml,统统去死吧! 首先建立一个Maven项

  • Spring Aop之AspectJ注解配置实现日志管理的方法

    最近项目要做一个日志功能,我用Spring Aop的注解方式来实现. 创建日志注解 package com.wyj.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lan

  • spring @Component注解原理解析

    这篇文章主要介绍了spring @Component注解原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.@controller 控制器(注入服务) 2.@service 业务(注入dao) 3.@repository dao(实现dao访问) 4.@component (把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>) 5.@Comp

  • Spring纯注解配置实现代码示例解析

    问题 我们发现,之所以我们现在离不开 xml 配置文件,是因为我们有一句很关键的配置: <!-- 告知spring框架在,读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中 --> <context:component-scan base-package="com.itheima"></context:component-scan> 如果他要也能用注解配置,那么我们就离脱离 xml 文件又进了一步. 另外,数据源和 JdbcTempl

  • Spring Web零xml配置原理以及父子容器关系详解

    前言 在使用Spring和SpringMVC的老版本进行开发时,我们需要配置很多的xml文件,非常的繁琐,总是让用户自行选择配置也是非常不好的.基于约定大于配置的规定,Spring提供了很多注解帮助我们简化了大量的xml配置:但是在使用SpringMVC时,我们还会使用到WEB-INF/web.xml,但实际上我们是完全可以使用Java类来取代xml配置的,这也是后来SpringBoott的实现原理.本篇就来看看Spring是如何实现完全的零XML配置. 正文 先来看一下原始的web.xml配置

随机推荐