首页 > 其他分享 >【Spring注解】2.@ComponentScan注解

【Spring注解】2.@ComponentScan注解

时间:2023-01-14 22:05:46浏览次数:42  
标签:basePackages default Spring FilterType value ComponentScan 注解 class

2.@ComponentScan

1.使用xml配置包扫描的方式

<!--包扫描,只要标注了@Controller/@Service/@Repository/@Component就可以被扫描到-->
<context:component-scan base-package="com.ooyhao"></context:component-scan>

【Spring注解】2.@ComponentScan注解_Spring

 

定义相应的Controller,service,dao层,并用相应的注解进行标注。

2.使用注解方式进行包扫描

//配置类==配置文件
@ComponentScan(value = {"com.ooyhao"})//可以定义多个。
@Configuration //告诉Spring这是一个配置类
public class MainConfig {

// 给容器中注册一个Bean,类型就是返回值的类型,id默认是用方法名作为id、
@Bean("person")
public Person person01(){
return new Person("李四",20);
}
}

注意:

xml方式,<context:component-scan></context:component-scan>是配置在beans.xml文件中的,所以只需要在MainConfig类上用@ComponentScan(value/basePackages="")来进行扫描。(value与basePackages作用一致)。

可以定义多个:(部分源码)

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {

/**
* Alias for {@link #basePackages}.
* <p>Allows for more concise annotation declarations if no other attributes
* are needed — for example, {@code @ComponentScan("org.my.pkg")}
* instead of {@code @ComponentScan(basePackages = "org.my.pkg")}.
*/
@AliasFor("basePackages")
String[] value() default {};

/**
* Base packages to scan for annotated components.
* <p>{@link #value} is an alias for (and mutually exclusive with) this
* attribute.
* <p>Use {@link #basePackageClasses} for a type-safe alternative to
* String-based package names.
*/
@AliasFor("value")
String[] basePackages() default {};

/**
* Type-safe alternative to {@link #basePackages} for specifying the packages
* to scan for annotated components. The package of each class specified will be scanned.
* <p>Consider creating a special no-op marker class or interface in each package
* that serves no purpose other than being referenced by this attribute.
*/
Class<?>[] basePackageClasses() default {};

测试代码:

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

结果:

 

【Spring注解】2.@ComponentScan注解_Spring注解_02

 

3.@Component的扫描规则

1.FilterType的源码(取值):

public enum FilterType {
ANNOTATION, //按照注解的方式
ASSIGNABLE_TYPE, //按照给定的类型
ASPECTJ, //按照ASPECTJ表达式
REGEX, //按照正则表达式
CUSTOM //自定义
}

2.@Componenet的源码

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class) //可以重复,说明可以写多个ComponentScan
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;

@AliasFor("classes")
Class<?>[] value() default {};

@AliasFor("value")
Class<?>[] classes() default {};

String[] pattern() default {};

}

}

3.MainConfig.java(排除)

//配置类==配置文件
@ComponentScan(value = {"com.ooyhao"},excludeFilters = {
@Filter(type = FilterType.ANNOTATION,value = {Controller.class}),
@Filter(type = FilterType.ASSIGNABLE_TYPE,value = {BookService.class})
})
@Configuration //告诉Spring这是一个配置类
public class MainConfig {

// 给容器中注册一个Bean,类型就是返回值的类型,id默认是用方法名作为id、
@Bean("person")
public Person person01(){
return new Person("李四",20);
}

}

(排除了@Controller标注的,以及BookService类型的)

【Spring注解】2.@ComponentScan注解_System_03

 

4.MainConfig.java(包含)

xml方式:

<!--包扫描,只要标注了@Controller/@Service/@Repository/@Component就可以被扫描到-->
<context:component-scan base-package="com.ooyhao" use-default-filters="false"></context:component-scan>
<!--需要使用use-default-filters来禁用默认的扫描规则-->

注解方式:

//配置类==配置文件
/*@ComponentScan(value = {"com.ooyhao"},excludeFilters = {
@Filter(type = FilterType.ANNOTATION,value = {Controller.class}),
@Filter(type = FilterType.ASSIGNABLE_TYPE,value = {BookService.class})
})*/
@ComponentScan(basePackages = "com.ooyhao",includeFilters = {
@Filter(type = FilterType.ANNOTATION,value = {Controller.class})
},useDefaultFilters = false)
@Configuration //告诉Spring这是一个配置类
public class MainConfig {

(只包含@Controller标注的)

【Spring注解】2.@ComponentScan注解_Spring注解_04

 

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class) //可以重复,说明可以写多个ComponentScan
public @interface ComponentScan {

可同时写多个@ComponentScan(JDK1.8)。也可以使用@ComponentScans();

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface ComponentScans {
ComponentScan[] value();
}

(配置多个@ComponentScan)

@ComponentScan(basePackages = "com.ooyhao",includeFilters = {
@Filter(type = FilterType.ANNOTATION,value = {Controller.class})//(按照注解)
},useDefaultFilters = false)
@ComponentScan(basePackages = "com.ooyhao",includeFilters = {
@Filter(type = FilterType.ANNOTATION,value = {Service.class})//包括子类(按照指定类型)
},useDefaultFilters = false)
@Configuration //告诉Spring这是一个配置类
public class MainConfig {

【Spring注解】2.@ComponentScan注解_Spring_05

 

5.自定义扫描规则

通过实现TypeFilter接口来自定义扫描规则的Filter

public interface TypeFilter {

/**
* @param metadataReader :当前正在扫描的类的信息
* @param metadataReaderFactory :可以获取到其他类的信息
*/
boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException;
}

自定义扫描过滤器

public class MyTypeFilter implements TypeFilter{

/**
* @param metadataReader :当前正在扫描的类的信息
* @param metadataReaderFactory :可以获取到其他类的信息
*/
@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();
System.out.println(annotationMetadata.getAnnotationTypes());//获得注解类型
System.out.println(resource.getURL());//获得资源路径
System.out.println(classMetadata.getClassName());//获得类名

if(classMetadata.getClassName().contains("er")) {
return true;
}
return false;
}
}

在Config.java上配置

@ComponentScan(basePackages = "com.ooyhao",includeFilters = {
/*@Filter(type = FilterType.ANNOTATION,value = {Controller.class}),*/
@Filter(type = FilterType.CUSTOM,value = {MyTypeFilter.class})
},useDefaultFilters = false)
@Configuration //告诉Spring这是一个配置类
public class MainConfig {

【Spring注解】2.@ComponentScan注解_Spring注解_06

 

总结:

为什么myTypeFilter会被扫描到:

由于我们扫描的基本包是com.ooyhao,所有在这个基本包下面的所有的类都会被扫描到进行过滤,而只有上述结果中的三个是包含"er"的,所有就会被扫描到。

标签:basePackages,default,Spring,FilterType,value,ComponentScan,注解,class
From: https://blog.51cto.com/u_12131813/6007916

相关文章

  • Sentinel注解支持详述
    Sentinel注解支持详述☞​​博客导航​​,​​带你有序的阅读和学习!​​官方文档:​​https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81​......
  • day01-Spring基本介绍
    Spring基本介绍1.官方资料和下载1.1Spring5下载直接访问https://repo.spring.io/ui/native/release/org/springframework/spring/,选择相应版本即可进入官网https......
  • (13)SpringBoot使用poi上传excel文件
      摘要:本文主要讲解,在SpringBoot项目中如何使用poi上传excel文件。SpringBoot整合poi和springmvc整合poi差别不大,springmvc整合poi也可以借鉴此文;由于后面打算写spring......
  • (11)SpringBoot整合EhCache做缓存
      摘要:本文介绍在SpringBoot项目中,如何使用EhCache做缓存。EhCache简介:EhCache是一个纯Java的进程内缓存框架,是Hibernate中默认的CacheProvider;其缓存的数据可以存放......
  • (8)SpringBoot整合JSP
    SpringBoot官方不推荐使用JSP来开发web页面,而是推荐如Thymeleaf,FreeMarker等模板引擎来开发,但是绝大部分做java的程序员还是习惯jsp;所以,本文先讲解SpringBoot如何支持jsp开......
  • 230114_50_SpringBoot入门
    主启动类详解packagecom.bill;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;@Spr......
  • SpringBoot中使用SpringSecurity
    1.maven配置<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>2.新建html页面去......
  • springboot中的一些常用的知识
    1.lomboklombok就是为了简化代码的@Data注释@Data@AllArgsConstructor@NoArgsConstructorpublicclassPerson{privateStringname;privateStringadd......
  • Redis 6 学习笔记 3 —— 用SpringBoot整合Redis的踩坑,了解事务、乐观锁、悲观锁
    SpringBoot整合Redis时踩到的坑jdk1.8环境,用idea的SpringInitializr创建springboot项目,版本我选的2.7.6。pom文件添加的依赖如下,仅供参考。注意commons-pool2选错版本......
  • Spring
    20223.1.14Spring简介1.Spring概览1.1官网地址:http://www.spring.io1.2为了降低Java开发的复杂性,Spring采取了以下4种关键策略:基于POJO的轻量级和最小侵入式编程......