今天主要从如下几个方面来介绍一下@ComponentScan注解:web
@ComponentScan注解是什么正则表达式
@ComponentScan注解的详细使用spring
1,@ComponentScan注解是什么数组
其实很简单,@ComponentScan主要就是定义扫描的路径从中找出标识了须要装配的类自动装配到spring的bean容器中app
2,@ComponentScan注解的详细使用ide
作过web开发的同窗必定都有用过@Controller,@Service,@Repository注解,查看其源码你会发现,他们中有一个共同的注解@Component,没错@ComponentScan注解默认就会装配标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中,好下面我们就先来简单演示一下这个例子测试
在包com.zhang.controller下新建一个UserController带@Controller注解以下:this
package com.zhang.controller;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
}
在包com.zhang.service下新建一个UserService带@Service注解以下:spa
package com.zhang.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
}
在包com.zhang.dao下新建一个UserDao带@Repository注解以下:3d
package com.zhang.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
}
新建一个配置类以下:
/**
* 主配置类 包扫描com.zhang
*
* @author zhangqh
* @date 2018年5月12日
*/
@ComponentScan(value="com.zhang")
@Configuration
public class MainScanConfig {
}
新建测试方法以下:
AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainScanConfig.class);
String[] definitionNames = applicationContext2.getBeanDefinitionNames();
for (String name : definitionNames) {
System.out.println(name);
}
运行结果以下:
mainScanConfig
userController
userDao
userService
怎么样,包扫描的方式比之前介绍的经过@Bean注解的方式是否是方便不少,这也就是为何web开发的同窗常常使用此方式的缘由了
上面只是简单的介绍了@ComponentScan注解检测包含指定注解的自动装配,接下来让咱们来看看@ComponentScan注解的更加详细的配置,在演示详细的配置以前,让咱们先看看@ComponentScan的源代码以下:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
/**
* 对应的包扫描路径 能够是单个路径,也能够是扫描的路径数组
* @return
*/
@AliasFor("basePackages")
String[] value() default {};
/**
* 和value同样是对应的包扫描路径 能够是单个路径,也能够是扫描的路径数组
* @return
*/
@AliasFor("value")
String[] basePackages() default {};
/**
* 指定具体的扫描的类
* @return
*/
Class<?>[] basePackageClasses() default {};
/**
* 对应的bean名称的生成器 默认的是BeanNameGenerator
* @return
*/
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
/**
* 处理检测到的bean的scope范围
*/
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
/**
* 是否为检测到的组件生成代理
* Indicates whether proxies should be generated for detected components, which may be
* necessary when using scopes in a proxy-style fashion.
* <p>The default is defer to the default behavior of the component scanner used to
* execute the actual scan.
* <p>Note that setting this attribute overrides any value set for {@link #scopeResolver}.
* @see ClassPathBeanDefinitionScanner#setScopedProxyMode(ScopedProxyMode)
*/
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
/**
* 控制符合组件检测条件的类文件 默认是包扫描下的 **/*.class
* @return
*/
String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
/**
* 是否对带有@Component @Repository @Service @Controller注解的类开启检测,默认是开启的
* @return
*/
boolean useDefaultFilters() default true;
/**
* 指定某些定义Filter知足条件的组件 FilterType有5种类型如:
* ANNOTATION, 注解类型 默认
ASSIGNABLE_TYPE,指定固定类
ASPECTJ, ASPECTJ类型
REGEX,正则表达式
CUSTOM,自定义类型
* @return
*/
Filter[] includeFilters() default {};
/**
* 排除某些过来器扫描到的类
* @return
*/
Filter[] excludeFilters() default {};
/**
* 扫描到的类是都开启懒加载 ,默认是不开启的
* @return
*/
boolean lazyInit() default false;
}
a,演示basePackageClasses参数,如咱们把配置文件改为以下:
@ComponentScan(value="com.zhang.dao",useDefaultFilters=true,basePackageClasses=UserService.class)
@Configuration
public class MainScanConfig {
}
测试结果以下:
mainScanConfig
userDao
userService
只有userDao外加basePackageClasses指定的userService加入到了spring容器中
b,演示includeFilters参数的使用以下:
在com.zhang.service包下新建一个UserService2类以下:注意没有带@Service注解
package com.zhang.service;
public class UserService2 {
}
配置类改为:
@ComponentScan(value="com.zhang",useDefaultFilters=true,
includeFilters={
@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
@Filter(type=FilterType.ASSIGNABLE_TYPE,classes={UserService2.class})
})
@Configuration
public class MainScanConfig {
}
运行结果以下:
mainScanConfig
userController
userDao
userService
userService2
userService2一样被加入到了spring容器
新增一个自定义的实现了TypeFilter的MyTypeFilter类以下:
/**
* 自定义过滤
*
* @author zhangqh
* @date 2018年5月12日
*/
public class MyTypeFilter implements TypeFilter {
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();
System.out.println("--->"+className);
// 检测名字包含Service的bean
if(className.contains("Service")){
return true;
}
return false;
}
}
修改主配置以下:
@ComponentScan(value="com.zhang",useDefaultFilters=true,
includeFilters={
@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})
})
@Configuration
public class MainScanConfig {
}
运行结果以下:
mainScanConfig
userController
userDao
userService
userService2
能够发现一样userService2被加入到了spring容器中
好了includeFilters参数就演示到这,另一个参数excludeFilters和includeFilters用户一摸同样,只是他是过滤出不加入spring容器中,感兴趣的同窗能够本身试试,我这边就不演示了
总结一下@ComponentScan的经常使用方式以下
自定扫描路径下边带有@Controller,@Service,@Repository,@Component注解加入spring容器
经过includeFilters加入扫描路径下没有以上注解的类加入spring容器
经过excludeFilters过滤出不用加入spring容器的类
自定义增长了@Component注解的注解方式
最后一种方式这边没有演示,算留给你们的一个小问题吧,感兴趣的同窗本身实现下,有疑问也欢迎留言
以上是今天文章的全部内容,欢迎你们吐槽
推荐阅读
更多优质文章请关注如下公众号查阅: