事件还原
demo结构
- com
- cap2
- config
- Cap2MainConfig.java
- controller
- OrderController.java
- dao
- OrderDao.java
- server
- OrderService.java
- config
- cap2
代码
主要是测试bean是否被扫描(里面的代码忽略)
@Controller
public class OrderController {
}
@Repository
public class OrderDao {
}
@Service
public class OrderService {
}
核心配置类
import com.cap1.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.Service;
/**
* ComponentScan 扫描组件
* value 包扫描的路径
* excludeFilters = Filter[] 指定扫描的时候按照什么规则排除那些组件
* includeFilters = Filter[] 指定扫描的时候只需要包含哪些组件
* type = FilterType.ANNOTATION 按照注解
* classes = {Service.class} 注解里面的Service
* useDefaultFilters = false 使用自定义扫描范围要改成false
* 只扫描我com.cap2下的带有@Service注解的类
*/
@Configuration//配置类负责统一加载bean
@ComponentScan(value = "com.cap2",includeFilters= {@ComponentScan.Filter(
type = FilterType.ANNOTATION,classes = {Service.class}
)},useDefaultFilters = false)
//ComponentScan扫描组件
public class Cap2MainConfig {
}
结果
@Test
public void test3() {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap2MainConfig.class);
String[] name = app.getBeanDefinitionNames();
for (String s : name) {
System.out.println(s);
}
}
这样的结果是我们应该看到的
问题
于是我就在想我是不是可以搞一个反的test()试一试
刚刚的结果:只扫描我com.cap2下的带有@Service注解的类
突发奇想:在com.cap2下排除带有@Service注解的类
说干就干
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Service;
@Configuration
@ComponentScan(value = "com.cap2",excludeFilters = {@ComponentScan.Filter(
type = FilterType.ANNOTATION,classes = {Service.class}
)},useDefaultFilters = false)
public class Cap2MainConfig {
}
测试类省略
按照我预先设想的应该会有:
orderController
orderDao
为什么会没有呢?
解决方案
查看源码
useDefaultFilters默认是true,扫描带有@Component ro @Repository ro @Service ro @Controller 的组件
其中@Repository @Service @Controller都实现了@Component
因为它们都有实现@Component所以在useDefaultFilters为false时,IOC容器不会去注入带有@Componen的类,它会实现我们自己定义的过滤规则,下面见源码
因为不会去加载,所以容器里面就没有Bean,当然因为没有所以它也不会去排除(脸黑)
总结
现在想想,我当时为什么会有这样的想法,哈哈哈哈
我以为第一个demo是通过加载排除(其实是直接找需要的,不通过全部加载然后排除)
误以为第二个也和第一个一样
结果它里面根本就没有bean,也排除不了!!!