@ComponentScan注解
1. @ComponentScan 注解
在配置类中只要标注了@ComponentScan 注解,Spring就可以自动扫描Value对应的包了
1.1. 配置类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import com.huximi.beans.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value = "com.huximi")
public class MainConfig {
@Bean("person")
public Person person() {
return new Person("huximi", 31);
}
}
|
以上扫描com.huximi包中的所有组件
1.2 单元测试类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| import com.huximi.config.MainConfig;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class IOCTest_1 {
@Test
public void test01() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
// 获取容器中的所有组件
String[] names = applicationContext.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
}
|
输出的结果
1
2
3
4
5
6
7
8
9
10
| org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookDao
bookServiceImpl
person
|
前面五个都是Spring自己的组件,其中mainConfig类是因为增加了@Configuration注解,bookController类是因为增加了@Controller注解,bookService类是因为增加了@Servide注解,bookDao类是因为增加了@Repository注解,pereson类是因为在mainConfig类的person方法中增加了@Bean注解
1.3 excludeFilters 排除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| import com.huximi.beans.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
@Configuration
@ComponentScan(value = "com.huximi", excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = { Controller.class })
})
public class MainConfig {
@Bean("person")
public Person person() {
return new Person("huximi", 31);
}
}
|
根据注解类型进行排除
1.4 includeFilters 仅包含
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| import com.huximi.beans.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
@Configuration
@ComponentScan(value = "com.huximi", includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = { Controller.class })
}, useDefaultFilters = false)
public class MainConfig {
@Bean("person")
public Person person() {
return new Person("huximi", 31);
}
}
|
使用仅包含includeFilters需要禁用默认的过滤规则,即将useDefaultFilters设置为false
1.5 FilterType.CUSTOM自定义过滤规则
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
public class MyTypeFilter implements TypeFilter {
/**
* @param metadataReader 读取到的当前正在扫描的信息
* @param metadataReaderFactory 可以获取到其他任何类的信息
* @return
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) {
// 获取当前类注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
System.out.println("获取当前类注解的信息:" + annotationMetadata.getAnnotationTypes());
// 获取到当前正在扫描的类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
// 获取当前类资源(类的路径)
Resource resource = metadataReader.getResource();
System.out.println("获取当前类资源(类的路径):" + resource);
String className = classMetadata.getClassName();
System.out.println("类名:" + className);
if (className.contains("dao")) {
return true;
}
return false;
}
}
|
1.5.1 自定义过滤,使用自定义的MyTypeFilter.class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| import com.huximi.beans.Person;
import com.huximi.filter.MyTypeFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
@Configuration
@ComponentScan(value = "com.huximi", includeFilters = {
@ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class }) }, useDefaultFilters = false
)
public class MainConfig {
@Bean("person")
public Person person() {
return new Person("huximi", 31);
}
}
|
总结
- excludeFilers = Filter[], 指定扫描的时候按照什么规则排除哪些组件
- includeFilers = Filter[], 指定扫描的时候按照什么规则包含哪些组件
- FilterType.ANNOTATION, 按照注解
- FilterType.ASSIGNABLE_TYPE,按照给定的类型
- FilterType.ASPECTJ,使用ASPECTJ表达式
- FilterType.REGEX,使用正则规则
- FilterType.CUSTOM,使用自定义规则
- @ComponentScan注解还可以叠加使用