三、Spring-包扫描注解@ComponentScan

在一个项目开发中,通常会把项目分为
一、DAO层(数据访问层):专门负责数据库交互 CRUD(增查改删),好比在mysql数据库里生成一条订单数据。java

二、Service层(业务逻辑层) : 负责业务逻辑的处理,好比购买东西的业务,须要调用DAO层的方法扣减商品记录里的库存数量,而后生成一条订单记录。mysql

三、Controller层(控制层) : 接收页面的请求,调用业务逻辑层去处理,将业务逻辑层处理返回的结果返回给页面。spring

spring中对每一层都提供了相应的注解进行标识:sql

spring还提供了 @Component 组件,没有明确的角色,只是标明该类要注册到spring容器中。数据库

spring可使用 @ComponentScan 注解扫描指定包下标有上面那些注解的类注册到spring容器中。数组

一、基础使用app

下面配置类使用了包扫描注解@ComponentScan,并指定了扫描的包名为com.suzhe.spring.basic.scan, spring启动的时候就会扫描该包下全部的符合条件的类,并注入到spring容器中。ide

@Configuration  //告诉Spring这是一个配置类
//包扫描:若是没有配置则默认扫描为当前类所在包及其子包
@ComponentScan(value = "com.suzhe.spring.basic.scan")
public class ScanConfig {
}

添加几个类:其中Message1 没有注解,不符合条件测试

@Controller
public class GreetingController {
}
@Service
public class GreetingService {

}
@Repository
public class GreetingDao {
    public String getMessage(){
        return "welcome";
    }
}
@Component
public class Message {

}
public class Message1 {

}

运行测试.net

@Test
	public void test1(){
		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(ScanConfig.class);
		//获取容器中全部注册的bean的name,返回一个数组
		String[] names = app.getBeanDefinitionNames();
		for(String name:names){
			System.out.println(name);
		}
	}

能够看出spring把指定包下符合条件的类都注册到了容器中

值得注意的是,这些注解都有一个 value属性,是指定注册到spring中实例的name,默认为 类名首字母小写。

咱们能够设置以下

@Service(value = "gs")
public class GreetingService {

}

再次运行测试,能够看到注册到spring中bean实例的name变成了gs。

同理,其余注解也同样。

 

二、扩展-包含过滤

注解@ComponentScan 还提供includeFilters属性指定扫描的时候只须要包含哪些组件。

其中Filter有下面几种过滤类型:

FilterType.ANNOTATION:按照注解
FilterType.ASSIGNABLE_TYPE:按照给定的类型;
FilterType.ASPECTJ:使用ASPECTJ表达式
FilterType.REGEX:使用正则指定
FilterType.CUSTOM:使用自定义规则

示例配置类1

该类配置了FilterType.ANNOTATION和FilterType.ASSIGNABLE_TYPE ,那么就只有注解为@Service的类和Message会被注册到spring容器中。

须要注意的是useDefaultFilters设置为false。

@Configuration  //告诉Spring这是一个配置类
//包扫描:若是没有配置则默认扫描为当前类所在包及其子包
@ComponentScan(value = "com.suzhe.spring.basic.scan",includeFilters ={
        @ComponentScan.Filter(type= FilterType.ANNOTATION, classes={Service.class}),
        @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,classes={Message.class}),
}, useDefaultFilters=false)
public class ScanIncludeConfig {


}

测试运行

@Test
	public void test2(){
		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(ScanIncludeConfig.class);
		String[] names = app.getBeanDefinitionNames();
		for(String name:names){
			System.out.println(name);
		}
	}

从下面的结果能够看出,只有两个符合过滤条件的类注入到了spring容器中。

 

同时咱们还能够自定义过滤器,以下

public class CustomTypeFilter implements TypeFilter{
	private ClassMetadata classMetadata;
	/*
	 * MetadataReader:读取到当前正在扫描类的信息
	 * MetadataReaderFactory:能够获取到其余任何类信息
	 */
	@Override
	public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException {
		//获取当前类注解的信息
		AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
		//获取当前正在扫描的类信息
		classMetadata = metadataReader.getClassMetadata();
		//获取当前类资源(类的路径)
		Resource resource = metadataReader.getResource();
		String className = classMetadata.getClassName();
		System.out.println("----->"+className);
		if(className.contains("Controller")){//当类名包含Controller字符, 则匹配成功,返回true
			return true;
		}
		return false;
	}

}

经过FilterType.CUSTOM 指定过滤器CustomTypeFilter ,那么spring就只会注册符合CustomTypeFilter过滤条件的类。

@Configuration  //告诉Spring这是一个配置类
//包扫描:若是没有配置则默认扫描为当前类所在包及其子包
@ComponentScan(value = "com.suzhe.spring.basic.scan",includeFilters ={
        @ComponentScan.Filter(type=FilterType.CUSTOM,classes={CustomTypeFilter.class}),
}, useDefaultFilters=false)
public class ScanIncludeCustomConfig {


}

测试运行

@Test
public void test02(){
   AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(ScanIncludeCustomConfig.class);
   String[] names = app.getBeanDefinitionNames();
   for(String name:names){
      System.out.println(name);
   }
}

能够看到只有符合条件的GreetingController 被注册了。

 

同时@ComponentScan还提供了排除的过滤功能:

useDefaultFilters=true excludeFilters = Filter[] :指定扫描的时候按照什么规则排除哪些组件

includeFilters是包含哪些,excludeFilters是排除哪些,其余的都同样,这里再也不作过多的说明。

相关文章
相关标签/搜索