@ComponentScan是用来扫描组件的,只要用@Service、@Repository、@Controller、@RestController、@Component注解的类都会被Spring实例化到IOC容器中去,和之前使用xml配置文件用到的标签:context:component-scan对应
@Configuration//告诉Spring这是一个配置文件
@ComponentScan(value = "com.booyue.tlh.annotation")//识别:@Service、@Repository、@Controller、@RestController、@Component
public class SpringConfig {
@Bean(name = "person")//给容器中注册一个bean
public Person getPerson() {
return new Person("Lisi", 20);
}
}
接着在包(子包也可以)com.booyue.tlh.annotation中创建事例Service、dao、controller等等
@RestController
public class PersonController {
}
@Service
public class PersonService {
}
@Repository
public class PersonDao {
}
接下来我们通过Debug就能从beanDefinitionMap中看到我们定义的Service、Controller、Dao等信息
当我我们不需要@ComponentScan为我们扫描到特定的组件的时候,这个时候我们就需要选用@ComponentScan的excludeFilters来定义规则。具体的Filter的类型,系统通过枚举类org.springframework.context.annotation.FilterType指定了有:ANNOTATION、ASPECTJ、REGEX、CUSTOM、ASSIGNABLE_TYPE
接下来我们把用@Service注解的来排除掉:
//告诉Spring这是一个配置文件
@Configuration
//识别:@Service、@Repository、@Controller、@RestController、@Component
@ComponentScan(value = "com.booyue.tlh.annotation", excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Service.class})
})
public class SpringConfig {
@Bean(name = "person")//给容器中注册一个bean
public Person getPerson() {
return new Person("Lisi", 20);
}
}
我们再次通过Debug调试的时候,就在Spring的beanDefinitionMap中找不到personService了,就只能看到personDao和personController
这里includeFilters和上面的excludeFilters用法一样,只不过这里的意思是只包含的意思。还有一点不同的是,我们在使用includeFilters的是和之前xml的方式一样需要将useDefaultFilters(默认值为true)设置成false,我们的includeFilters才会生效。通过这个配置,你会发现在Spring的IOC容器中就只会出现personService了。(这里我们通过ASSIGNABLE_TYPE又指定了一个PersonController的类型,只要是PersonController类及其子类也会被实例化到Spring的IOC容器中去)
//告诉Spring这是一个配置文件
@Configuration
//识别:@Service、@Repository、@Controller、@RestController、@Component
@ComponentScan(value = "com.booyue.tlh.annotation", includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Service.class}),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {PersonController.class})
}, useDefaultFilters = false)
public class SpringConfig {
@Bean(name = "person")//给容器中注册一个bean
public Person getPerson() {
return new Person("Lisi", 20);
}
}
我们通过实现TypeFilter 接口就能实现自定义的Filter
public class MyTypeFilter implements TypeFilter {
/**
* @param metadataReader:获取到当前正在扫描的类的信息
* @param metadataReaderFactory:可以获取到其他任何类的信息
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
ClassMetadata classMetadata = metadataReader.getClassMetadata();
String className = classMetadata.getClassName();
System.out.println("---->" + className);
if (className.contains("er"))
return true;
return false;
}
}
将我们自定义的Filter配置到@ComponentScan中就能让我们的Filter生效了
//告诉Spring这是一个配置文件
@Configuration
@ComponentScans({
// //识别:@Service、@Repository、@Controller、@RestController、@Component
// @ComponentScan(value = "com.booyue.tlh.annotation", includeFilters = {
// @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Service.class}),
// @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {PersonController.class})
// }, useDefaultFilters = false),
@ComponentScan(value = "com.booyue.tlh.annotation", includeFilters = {
@ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyTypeFilter.class)
}, useDefaultFilters = false)
})
public class SpringConfig {
@Bean(name = "person")//给容器中注册一个bean
public Person getPerson() {
return new Person("Lisi", 20);
}
}