@ComponentScan作用:指定扫描哪些包,然后将被扫描到的类中需要注入IOC容器的类进行注入。
-------------------------------------------------------------------------------------------------------------------------------------------------------
MainConfig
//指定当前类为配置类
@Configuration
//扫描注解
@ComponentScan(value = "com.zc.test3")
public class MainConfig {
// 之前是通过这种方式返回,本次通过扫描,@ComponentScan注解实现
// 创建该类的对象,加入IOC容器中
/*@Bean
public Person person(){
return new Person("zc2","27");
}*/
}
com.zc.test3包下有controller,service,dao包,对应的类可以用@Controller,@Service,@Repository指定。
这样在容器启动的时候就可以将controller类,service类,dao类注入到容器中
接下来看看@ComponentScan的源码
package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.type.filter.TypeFilter;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface ComponentScan {
//包扫描路径 可以多个
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
boolean useDefaultFilters() default true;
Filter[] includeFilters() default {};
Filter[] excludeFilters() default {};
boolean lazyInit() default false;
@Retention(RetentionPolicy.RUNTIME)
@Target({})
@interface Filter {
FilterType type() default FilterType.ANNOTATION;
Class<?>[] value() default {};
String[] pattern() default {};
}
}
1、String[] value() default {};
指定@ComponentScan扫描路径,如下
@ComponentScan(value = {"com.zc.entity"})
2、String[] basePackages() default {};
和1含义一样,可以看到该方法上有@AliasFor("value")
@AliasFor() 表明同一个注解的不同属性起着相同的作用。简单理解为别名
3、Class<?>[] basePackageClasses() default {};
指定具体扫描哪个类,很好理解
4、Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
对应的bean名称的生成器,默认的是BeanNameGenerator
5、Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
处理检测到的bean的scope范围,后面还要学习@Scope,常用的属性有prototype,singleton
6、ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
是否为检测到的组件生成代理
7、String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
控制符合组件检测条件的类文件 默认是包扫描下的 **/*.class
8、boolean useDefaultFilters() default true;
是否对带有@Component @Repository @Service @Controller注解的类开启检测,默认是开启的
9、Filter[] includeFilters() default {};
指定哪些实体类加入容器,可以根据注解,表达式,正则,给定的类型
10、Filter[] excludeFilters() default {};
指定哪些实体类不被加入容器,可以根据注解,表达式,正则,给定的类型等方式
11、boolean lazyInit() default false;
扫描到的类是都开启懒加载 ,默认是不开启的
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
最常用的是第九个includeFilters(),指定哪些实体类加入容器,下面看例子
使用includeFilters()时,还要学习一下第八个includeFilters,将它设置为false,让默认设置失效,要不然我们设置不生效。
此时,配置类如下,表示项目启动时,只将com.zc.study02包下含有Controller注解的类创建,并加入到容器中
@Configuration
//扫描指定目录下的包
@ComponentScan(value = "com.zc.study02",includeFilters={
@Filter(type=FilterType.ANNOTATION, classes={Controller.class})
},useDefaultFilters=false)
public class MainConfig {
}
同理,第十个 excludeFilters()和第九个类似。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
注意上面中的这一行
@Filter(type=FilterType.ANNOTATION, classes={Controller.class})
ANNOTATION 表示根据注解来扫描,除此之外,还可以根据具体的类进行扫描
@Filter(type=FilterType.ASSIGNABLE_TYPE, classes={MyClass.class})
FilterType 共有五种
ANNOTATION,ASSIGNABLE_TYPE,ASPECTJ,REGEX,CUSTOM