组件注册 02 @ComponentScan 自动扫描组件 & 指定扫描规则
资源准备
package com.example.annotations.controller;
import org.springframework.stereotype.Controller;
@Controller
public class BookController {
}
package com.example.annotations.service;
import org.springframework.stereotype.Service;
@Service
public class BookService {
}
传统方式
beans.xml中:
<context:component-scan base-package="com.example.annotations.controller"></context:component-scan>
<bean id="person" class="com.example.annotations.bean.Person">
<property name="name" value="lxl"/>
<property name="age" value="21"/>
</bean>
此后 只要在该包下标注了 @Controller @Service @Repository @Component 都会被加载进IOC容器
测试:
@Test
void packageScanTest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String str:beanDefinitionNames){
System.out.println(str);
}
}
有person是因为在beans.xml手动注入的
注解方式 @ComponentScan()
使用的时候注释掉 beans.xml中的 包扫描属性
<!-- 这行 注释掉 -->
<!-- <context:component-scan base-package="com.example.annotations.controller"></context:component-scan>-->
<bean id="person" class="com.example.annotations.bean.Person">
<property name="name" value="lxl"/>
<property name="age" value="21"/>
</bean>
直接扫描
-
在MainConfig上加上注解 @Configuration(value = “com.example.annotations.service”)
// @Configuration : 告诉Spring这是个配置类 @Configuration @ComponentScan(value = "com.example.annotations") // 包扫描注解:只要在该包下标注了 @Controller @Service @Repository @Component 都会被加载进IOC容器 public class MainConfig { //给容器注入一个bean,类型为返回值的类型,id默认使用方法的id @Bean("person") public Person getPerson(){ return new Person("qd",21); } }
-
测试
@Test void packageScanTest(){ //xml // ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); //配置类测试 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class); String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames(); for (String str:beanDefinitionNames){ System.out.println(str); } }
-
结果:
注入进容器的id默认是类名的小写(不严格是小写,实际为驼峰命名)
不玩钱为什么会有mainConfig?MainConfig.class上标注了@Configuration注解
@Configuration 源码
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component // 有这个注解,会被加载进容器 public @interface Configuration { @AliasFor( annotation = Component.class ) String value() default ""; boolean proxyBeanMethods() default true; }
过滤规则
@includeFilters
// @Configuration : 告诉Spring这是个配置类
@Configuration
@ComponentScan(value = "com.example.annotations",
includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = { Service.class,Controller.class})},
useDefaultFilters = false
)
public class MainConfig {
//给容器注入一个bean,类型为返回值的类型,id默认使用方法的id
@Bean("person")
public Person getPerson(){
return new Person("qd",21);
}
}
测试:
@excludeFilters
???
// @Configuration : 告诉Spring这是个配置类
@Configuration
@ComponentScan(value = "com.example.annotations",
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class, Service.class})},
useDefaultFilters = false
)
public class MainConfig {
//给容器注入一个bean,类型为返回值的类型,id默认使用方法的id
@Bean("person")
public Person getPerson(){
return new Person("qd",21);
}
}
测试:可看到过滤掉了controller和Service