Spring注解-(四)@ComponentScan的使用详解

本文最后更新于:June 13, 2022 am

Spring 是目前主流的 Java Web 开发框架,是 Java 世界最为成功的框架。Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。该框架是一个轻量级的开源框架,具有很高的凝聚力和吸引力。Spring 框架不局限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何 Java 应用都可以从 Spring 中受益。Spring 框架还是一个超级粘合平台,除了自己提供功能外,还提供粘合其他技术和框架的能力。

目录

作用:会去扫描指定路径下面的@Component注解。

除了扫描路径之外,它还有两个重要的参数:includeFilters、excludeFilters。

includeFilters属性

首先来看一个示例:

自定义注解代替@Component:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.SpringTestAnnotation.TestValue;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @Author DragonOne
* @Date 2022/6/12 08:08
* @墨水记忆 www.tothefor.com
*/

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface OurAnno {
}

注解上面的两个直接Copy的是@Component中的。

然后使用自定义注解从而代替原本的@Component注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.SpringTestAnnotation.TestValue;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
* @Author DragonOne
* @Date 2022/6/10 21:56
* @墨水记忆 www.tothefor.com
*/
@OurAnno
public class OrderS {
}

配置类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.SpringTestAnnotation;

import com.SpringTestAnnotation.TestValue.OrderS;
import com.SpringTestAnnotation.TestValue.OurAnno;
import com.SpringTestAnnotation.TestValue.Per;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
@ComponentScan("com.SpringTestAnnotation")
public class TestConfig {

}

然后测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.SpringTestAnnotation;

import com.SpringTestAnnotation.TestValue.Per;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
public class TestAnnotation {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestConfig.class);
System.out.println(applicationContext.getBean("orderS"));
}
}

结果出现报错:表示找不到Bean。

1
No bean named 'orderS' available

我们再修改配置类中的@ComponentScan注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.SpringTestAnnotation;

import com.SpringTestAnnotation.TestValue.OrderS;
import com.SpringTestAnnotation.TestValue.OurAnno;
import com.SpringTestAnnotation.TestValue.Per;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Component;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
@ComponentScan(value = "com.SpringTestAnnotation",includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,value = OurAnno.class))
public class TestConfig {

}

然后再跑上面的测试代码。可以发现这时是可以成功运行的。

作用

通过添加此属性,从而指定符合某种条件下的类就可以是我们的Bean。(个人理解:就是修改了成为Bean的条件)

下面代码的作用:通过添加的包含过滤器(includeFilters),只要类上有OurAnno这个注解,就会把这个类当成是一个Bean(type = FilterType.ANNOTATION,value = OurAnno.class)。

1
@ComponentScan(value = "com.SpringTestAnnotation",includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,value = OurAnno.class))

其中,type有很多类型:

1
2
3
4
5
6
7
8
9
10
public enum FilterType {
ANNOTATION,
ASSIGNABLE_TYPE,
ASPECTJ,
REGEX,
CUSTOM;

private FilterType() {
}
}

excludeFilters

作用

通过上面的属性可以类比这个属性,上面的包含,而这个属性就是排除。即作用和上面的includeFilters属性作用相反。也就是说:只要类上有OurAnno这个注解,那么这个类就不能成为一个Bean(type = FilterType.ANNOTATION,value = OurAnno.class)。

总结

ComponentScan中还有一种方式,叫作:扫描索引。即在文件进行设置。这种方式这里就不再记录了,可自行搜索。