暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

@SpringBootApplication 之 @ComponentScan

TechStyle 2021-06-21
750

原理

@SpringBootApplication 是一个复合注解,包括

  • @SpringBootConfiguration

  • @EnableAutoConfiguration

  • @ComponentScan

Note:

@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
  • excludeFilters

    Specifies which types are not eligible for component scanning

  • @Filter

    Filter annotation

  • FilterType.CUSTOM

    Filter candidates using a given custom implementation

  • classes:

    Filter specific class,include TypeExcludeFilterAutoConfigurationExcludeFilter

@ComponentScan 源码

Note:

  • 通常自定义一个Spring Bean,一般在类上加上注解 @Component、@Service、@Controller,定义好后,需要使用@ComponentScan 来告诉Spring IoC 容器去哪里装载自定义的Spring Bean。

  • @SpringBootApplication 包含了@ComponentScan,所以@SpringBootApplication注解所在包及其子包目录下的Spring Bean都会被扫描并装载到Spring IoC容器。

  • 如果自定义的一个Spring Bean,不在@SpringBootApplication 注解所在包及其子包目录下,需要手动加上@ComponentScan 注解并指定自定义Spring Bean所在的包。


示例

Project Directory


Maven Dependency

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>


<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/>
</parent>


<groupId>org.fool</groupId>
<artifactId>hellospring</artifactId>
<version>1.0-SNAPSHOT</version>


<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>


<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>


<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>


</project>


SRC

MockComponentScan.java

package org.fool.spring.component.scan;


import org.springframework.stereotype.Service;


@Service
public class MockComponentScan {


public MockComponentScan() {
System.out.println("MockComponentScan init...");
}


@Override
public String toString() {
return "MockComponentScan{}";
}
}


MainTest.java

package org.fool.spring.component.core;


import org.fool.spring.component.scan.MockComponentScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;


@SpringBootApplication
@ComponentScan("org.fool.spring.component.scan")
public class MainTest {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(MainTest.class, args);
MockComponentScan bean = context.getBean(MockComponentScan.class);
System.out.println(bean);
}
}

Note:  

MockComponentScan.java 和 打上@SpringBootApplication 注解的MainTest.java 不在同一个包中

@ComponentScan("org.fool.spring.component.scan")


Run

反之如果将 @ComponentScan 注释掉

再次运行MainTest.java,会抛出异常

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.fool.spring.component.scan.MockComponentScan' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1127)
at org.fool.spring.component.core.MainTest.main(MainTest.java:14)



泰克风格 只讲干货 不弄玄虚

文章转载自TechStyle,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论