<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
在早期的时候使用的是bean.xml的context:component-scan去扫描的包
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!--扫描包-->
<context:component-scan base-package="com.dmg">
</context:component-scan>
</beans>
public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");
String[] beanDefibnitionNames = applicationContext.getBeanDefinitionNames();
for (String s : beanDefibnitionNames) {
System.out.println(s);
}
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/c9d6804b9e7b7ff06a135a90e99a49a3.png)
但是我们使用@ComponentScan(value = "com.dmg")
这个注解,去扫描某一个包,就不用在xml去配置了
@Component
public class TestComponent {
}
@Controller
public class TestController {
}
@Service
public class TestService {
}
@ComponentScan(value = "com.dmg")
public class TestConfig {
}
public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(TestConfig.class);
String[] beanDefibnitionNames = applicationContext.getBeanDefinitionNames();
for (String s : beanDefibnitionNames) {
System.out.println(s);
}
}
}
可以看到,@Component,@Controller,@Service这些注解都扫描进来了
只要加了这些注解,被扫描到,那么就会加载到ioc容器中
![](https://i-blog.csdnimg.cn/blog_migrate/3c81ecf631f70a26bd14d23198925a42.png)
我们也可以做使用excludeFilters来进行过滤,比如排除@Controller,和@Service的注解
@ComponentScan(value = "com.dmg",excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})
})
public class TestConfig {
}
![](https://i-blog.csdnimg.cn/blog_migrate/5712814988f8d0140ebe56f4665176f4.png)
我们还可以使用includeFilters只使用某一些注解
结合useDefaultFilters = false使用默认筛选器,要不然不生效
@ComponentScan(value = "com.dmg",includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})
},useDefaultFilters = false)
public class TestConfig {
}
![](https://i-blog.csdnimg.cn/blog_migrate/23935a2b3105f32a0d15c0d8377db14e.png)
FilterType.ANNOTATION是使用注解的类型
我们还可以使用 FilterType.ASSIGNABLE_TYPE,来指定一个类
public class Sp {
}
@ComponentScan(value = "com.dmg",includeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Sp.class})
},useDefaultFilters = false)
public class TestConfig {
}
![](https://i-blog.csdnimg.cn/blog_migrate/d8253ba5028875c20f9e60bf4ac25e60.png)
我们还可以设置自定义的类型FilterType.CUSTOM
创建一个MyFilter类实现TypeFilter
@ComponentScan(value = "com.dmg",includeFilters = {
@ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyFilter.class})
},useDefaultFilters = false)
public class TestConfig {
}
public class MyFilter implements TypeFilter {
/**
*
* @param metadataReader 读取当前正在扫描的类信息
* @param metadataReaderFactory 可以获取到其他类的任何信息
* @return
* @throws IOException
*/
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类注解信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取资源信息
Resource resource = metadataReader.getResource();
//获取类路径信息
String className = classMetadata.getClassName();
System.out.println("============"+className);
//模拟是Sp这个类生效 注入到ioc容器中
if(className.contains("Sp")){
return true;
}
//不注入到ioc容器中
return false;
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/d93a6cf70a7630d7fa258a7370f21a12.png)