Spring 与组件注入相关的注解之 @ComponentScans/@ComponentScan/@Controller/@Service/@Repository/@Component

11 篇文章 0 订阅
11 篇文章 0 订阅
前言:

通过上一个demo,应该能初步体会到spring 基于注解的开发流程。那下面介绍几个新的与组件注入相关的注解:@ComponentScans/@ComponentScan/@Controller/@Service/@Repository/@Component

准备工作:

新建 controller、service、dao三个package,并在其中分别定义三个类:如 UserController、UserService、UserDao(三各类当然在三个不同的package下,类中可以暂时什么也不定义)。

实验:

除了通过@Bean之外,还可以通过下面这样的方式将其分别注入到IOC容器中:

  1. 首先,分别在 UserController、UserService、UserDao 这三个类上标注上 @Controller、@Service、@Repository 注解(这一点学过spring的应该都不陌生)。
@Controller
public class UserController {

}

@Service
public class UserService {

}

@Repository
public class UserDao {

}
  1. 其次,在SpringConfig1配置类上使用 @ConfigurationScan 注解。该注解最简单的用法就是通过 bacePackages 属性指定扫描哪些包及其子包下面的类,将其注入到IOC容器。例如
@Configuration 
@ComponentScan(basePackages="com.uestc.auto.xiaoxie")
public class SpringConfig1 {
	@Bean
	public Person person(){
		return new Person("kristina", 24);
	}
}

  1. 编写测试方法,看新定义的三个类有没有注入到容器中。
// 包扫描
	@Test
	public void testComponentScan() {
		// 获取ioc容器中所有bean的name
		String[] names = context.getBeanDefinitionNames();
		for (String name : names) {
			System.out.println(name);
		}
	}
  1. 该注解还有一些很常用的属性。我们可以点进去查看详细信息:首先可以看到这是一个“可重复”注解 ~ @Repeatable 注解,即我们可以使用多个 @ComponentScan 定义不同的扫描规则,或者使用 @ComponentScans 包含多个 @ComponentScan。
    @ComponentScan注解@ComponentScan注解
  • includeFilters:指定在进行包扫描的时候,按照什么规则包含哪些包;但是 includeFilters 需要结合 useDefaultFilters=false 一起使用,否则默认扫描全部;
  • excludeFilters:指定在进行包扫描的时候,按照什么规则排除哪些包。
  • 按住 Ctrl 键,点击 includeFilters 或者 excludeFilters 前面的 Filter,可以看到这又是一个注解(@Filter):
    在这里插入图片描述
    @Filter 注解的 type 属性用于指定包扫描规则,type 属性的取值为一个枚举类 FilterType。且通过 type 属性上面的注释,我们可以进一步明确:
type属性的取值对应的含义
FilterType.ANNOTATION默认取值 ,按照指定的注解扫描/排除包
FilterType.ASSIGNABLE_TYPE按照指定的类型扫描/排除包
FilterType.ASPECTJ还可以写 aspectj 表达式
FilterType.REGEX还可以写正则表达式
FilterType.CUSTOM还可以自定义包扫描规则
  1. 示例代码:
@Configuration
@ComponentScans(value={
	@ComponentScan(basePackages="com.uestc.auto.xiaoxie", useDefaultFilters=false, includeFilters={
			@Filter(type=FilterType.ANNOTATION, classes={Controller.class, Service.class}), 
			@Filter(type=FilterType.ASSIGNABLE_TYPE, classes={UserDao.class}),
			@Filter(type=FilterType.CUSTOM, classes={MyTypeFilter.class})})
})
public class SpringConfig1 {
	@Bean(value="person") 
	public Person person01(){
		return new Person("kristina", 24);
	}
	
}

注意,扫描规则的最后一行 @Filter(type=FilterType.CUSTOM, classes={MyTypeFilter.class}) 为自定义的。
在这里插入图片描述
从上图中可以看出,自定义包扫描需要实现 TypeFilter 接口。如下所示:

/*
 * 自定义包扫描规则
 */
public class MyTypeFilter implements TypeFilter {

	/*
	 * @param metadataReader:当前类的信息
	 * @param metadataReaderFactory:可以从中获取到其它任何类的信息
	 * @return true:扫描当前类
	 * 		 	 false:过滤当前类
	 * @throws IOException
	 */
	@Override
	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();
		if(className.equals("userDao")){
			return true;
		}
		return false;
	}
}
  1. 任意组合包扫描规则,再次调用第三步的测试方法,体会有哪些变化。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值