Spring框架之@CompentScan注解使用讲解,超详细

简介: Spring框架之@CompentScan注解使用讲解,超详细


一、@CompentScan


组件注册-@ComponentScan-自动扫描组件&指定扫描规则


1)在xml文件配置的方式,我们可以这样来进行配置:


<!-- 包扫描、只要标注了@Controller、@Service、@Repository,@Component -->
<context:component-scan base-package="cn.liuliang"/>


2)以前是在xml配置文件里面写包扫描,现在我们可以在配置类里面写包扫描:


@Configuration //声明该类是配置类
@ComponentScan("cn.liuliang.studysoundcodespring") //包扫描
public class SpringConfig {
    /**
     * 向容器中主入一个bean组件
     * @return
     */
    @Bean
    public User user(){
        // 通过new创建对象,放入容器中
        return new User("j3-liuliang",28);
    }
}


3)结果


image.png


从上面的测试结果我们可以发现主配置类 SpringConfig也是IOC容器里面的组件,也被纳入了IOC容器的管理:


我们从@Configuration 这个注解点进去就可以发现这个注解上也标注了 @Component 的这个注解,也纳入到IOC容器中作为一个组件:


@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
  /**
   * Explicitly specify the name of the Spring bean definition associated
   * with this Configuration class. If left unspecified (the common case),
   * a bean name will be automatically generated.
   * <p>The custom name applies only if the Configuration class is picked up via
   * component scanning or supplied directly to a {@link AnnotationConfigApplicationContext}.
   * If the Configuration class is registered as a traditional XML bean definition,
   * the name/id of the bean element will take precedence.
   * @return the specified bean name, if any
   * @see org.springframework.beans.factory.support.DefaultBeanNameGenerator
   */
  String value() default "";
}


我们在 @ComponentScan 这个注解上,也是可以指定要排除哪些包或者是只包含哪些包来进行管理:里面传是一个Filter[]数组


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
    // 忽略其他源代码
    /**
   * Indicates whether automatic detection of classes annotated with {@code @Component}
   * {@code @Repository}, {@code @Service}, or {@code @Controller} should be enabled.
   */
    // 默认扫描规则,默认值true
  boolean useDefaultFilters() default true;
  /**
   * Specifies which types are eligible for component scanning.
   * <p>Further narrows the set of candidate components from everything in {@link #basePackages}
   * to everything in the base packages that matches the given filter or filters.
   * <p>Note that these filters will be applied in addition to the default filters, if specified.
   * Any type under the specified base packages which matches a given filter will be included,
   * even if it does not match the default filters (i.e. is not annotated with {@code @Component}).
   * @see #resourcePattern()
   * @see #useDefaultFilters()
   */
    // 只扫描指定路径包,不过要将默认扫描规则关闭
  Filter[] includeFilters() default {};
  /**
   * Specifies which types are not eligible for component scanning.
   * @see #resourcePattern
   */
    // 排除一些包不扫描
  Filter[] excludeFilters() default {};
}


1.1 excludeFilters

那接下来我们可以事实如下操作:


excludeFilters:排除某某不扫描


@Configuration //声明该类是配置类
//@ComponentScan("cn.liuliang.studysoundcodespring") //包扫描
@ComponentScan(value = "cn.liuliang.studysoundcodespring",excludeFilters = {
        //这里面是一个@Filter注解数组,FilterType.ANNOTATION表示的排除的规则 :按照注解的方式来进行排除
        //classes = {Controller.class,Service.class}表示的是标有这些注解的类给排除掉
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})
})
public class SpringConfig {
    /**
     * 向容器中主入一个bean组件
     * @return
     */
    @Bean
    public User user(){
        // 通过new创建对象,放入容器中
        return new User("j3-liuliang",28);
    }
}


image.png


1.2 includeFilters

includeFilters:指定在扫描的时候,只需要包含哪些组件


在用xml文件配置的方式来进行配置的时候,还要禁用掉默认的配置规则,只包含哪些组件的配置才能生效


<context:component-scan base-package=“cn.liuliang.springannotationdemo” use-default-filters=“false”/>


@Configuration //声明该类是配置类
//@ComponentScan("cn.liuliang.studysoundcodespring") //包扫描
@ComponentScan(value = "cn.liuliang.studysoundcodespring",includeFilters = {
    //这里面是一个@Filter注解数组,FilterType.ANNOTATION表示的排除的规则 :按照注解的方式来进行扫描
    //classes = {Repository.class}表示的是只扫描标有这些注解的类
    @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Repository.class})
  // 禁用掉默认的配置规则
},useDefaultFilters = false)
public class SpringConfig {
    /**
     * 向容器中主入一个bean组件
     * @return
     */
    @Bean
    public User user(){
        // 通过new创建对象,放入容器中
        return new User("j3-liuliang",28);
    }
}


image.png


@ComponentScan这个注解是可以重复定义的:来指定不同的扫描策略


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class) //可重复定义
public @interface ComponentScan {
}


那我们可以如下配置:但是这样写的话,就必须要java8及以上的支持


@Configuration //声明该类是配置类
//@ComponentScan("cn.liuliang.studysoundcodespring") //包扫描,如下两个扫描配置相当于这一个配置
@ComponentScan(value = "cn.liuliang.studysoundcodespring",includeFilters = {
    //这里面是一个@Filter注解数组,FilterType.ANNOTATION表示的排除的规则 :按照注解的方式来进行扫描
    //classes = {Repository.class}表示的是只扫描标有这些注解的类
    @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Repository.class})
},useDefaultFilters = false)
@ComponentScan(value = "cn.liuliang.studysoundcodespring",excludeFilters = {
    //这里面是一个@Filter注解数组,FilterType.ANNOTATION表示的排除的规则 :按照注解的方式来进行扫描
    //classes = {Repository.class}表示的是不扫描标有这些注解的类
    @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Repository.class})
})
public class SpringConfig {
    /**
     * 向容器中主入一个bean组件
     * @return
     */
    @Bean
    public User user(){
        // 通过new创建对象,放入容器中
        return new User("j3-liuliang",28);
    }
}


二、 ComponentScans


我们还可以用 @ComponentScans来定义多个扫描规则:里面是@ComponentScan规则的数组


//告诉Spring这是一个配置类
@Configuration
@ComponentScans(
        value = {
                @ComponentScan(value = "cn.liuliang.springannotationdemo",includeFilters = {
                        //这里面是一个@Filter注解数组,FilterType.ANNOTATION表示的排除的规则 :按照注解的方式来进行扫描
                        //classes = {Controller.class}表示的是只扫描标有这些注解的类
                        @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})
                },useDefaultFilters = false)
                ,@ComponentScan(value = "cn.liuliang.springannotationdemo")
        }
)
public class PersionConfig {
}


2.1 FilterType

组件注册-自定义TypeFilter指定过滤规则

我们可以来看看有哪几种过滤规则:


public enum FilterType {
    // 按照注解类型 比如@Controller @Service @Repository @Compent
  ANNOTATION,
    // 按照给定的类型来进行匹配
  ASSIGNABLE_TYPE,
    // 表达式来进行匹配,这个不常用
  ASPECTJ,
    // 按照正则表达式的方式来进行匹配
  REGEX,
    // 我们可以自己来写一个匹配规则的类:MyTypeFilter,这个类要实现TypeFilter这个接口
  CUSTOM
}


我们来说说最后一种:自定义匹配规则FilterType.CUSTOM

我们可以自己来写一个匹配规则的类:MyTypeFilter,这个类要实现TypeFilter这个接口


public class MyTypeFilter implements TypeFilter {
    /**
     *
     * @param metadataReader  the metadata reader for the target class 读取到当前正在扫描的类的信息
     * @param metadataReaderFactory a factory for obtaining metadata readers 可以获取到其他任何类的信息
     * @return
     * @throws IOException
     */
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //获取到当前类注解的信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //获取当前类的资源的信息(比如类的路径)
        Resource resource = metadataReader.getResource();
        //获取到当前正在扫描的类的信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        String className = classMetadata.getClassName();
        System.out.println("通过自定义的匹配规则--->"+className);
        // false表示不扫描该组件
        return false;
    }
}


这个时候,我们就可以这样来用了:使用FilterType.CUSTOM


//告诉Spring这是一个配置类
@Configuration
@ComponentScan(value = "cn.liuliang.springannotationdemo",includeFilters = {
        //自定义匹配的规则
        @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class}),
},useDefaultFilters = false)
public class SpringConfig {
}


结束语


  • 由于博主才疏学浅,难免会有纰漏,假如你发现了错误或偏见的地方,还望留言给我指出来,我会对其加以修正。
  • 如果你觉得文章还不错,你的转发、分享、点赞、留言就是对我最大的鼓励。
  • 感谢您的阅读,十分欢迎并感谢您的关注。


image.png

目录
相关文章
|
14天前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
96 26
|
17天前
|
缓存 Java 数据库
SpringBoot缓存注解使用
Spring Boot 提供了一套方便的缓存注解,用于简化缓存管理。通过 `@Cacheable`、`@CachePut`、`@CacheEvict` 和 `@Caching` 等注解,开发者可以轻松地实现方法级别的缓存操作,从而提升应用的性能和响应速度。合理使用这些注解可以大大减少数据库的访问频率,优化系统性能。
163 89
|
2月前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
181 73
|
4天前
|
监控 Java Spring
SpringBoot:SpringBoot通过注解监测Controller接口
本文详细介绍了如何通过Spring Boot注解监测Controller接口,包括自定义注解、AOP切面的创建和使用以及具体的示例代码。通过这种方式,可以方便地在Controller方法执行前后添加日志记录、性能监控和异常处理逻辑,而无需修改方法本身的代码。这种方法不仅提高了代码的可维护性,还增强了系统的监控能力。希望本文能帮助您更好地理解和应用Spring Boot中的注解监测技术。
33 16
|
17天前
|
SQL Java 数据库连接
对Spring、SpringMVC、MyBatis框架的介绍与解释
Spring 框架提供了全面的基础设施支持,Spring MVC 专注于 Web 层的开发,而 MyBatis 则是一个高效的持久层框架。这三个框架结合使用,可以显著提升 Java 企业级应用的开发效率和质量。通过理解它们的核心特性和使用方法,开发者可以更好地构建和维护复杂的应用程序。
106 29
|
6天前
|
XML Java 开发者
通过springboot框架创建对象(一)
在Spring Boot中,对象创建依赖于Spring框架的核心特性——控制反转(IoC)和依赖注入(DI)。IoC将对象的创建和管理交由Spring应用上下文负责,开发者只需定义依赖关系。DI通过构造函数、setter方法或字段注入实现依赖对象的传递。Spring Boot的自动配置机制基于类路径和配置文件,自动为应用程序配置Spring容器,简化开发过程。Bean的生命周期包括定义扫描、实例化、依赖注入、初始化和销毁回调,均由Spring容器管理。这些特性提高了开发效率并简化了代码维护。
|
1月前
|
开发框架 运维 监控
Spring Boot中的日志框架选择
在Spring Boot开发中,日志管理至关重要。常见的日志框架有Logback、Log4j2、Java Util Logging和Slf4j。选择合适的日志框架需考虑性能、灵活性、社区支持及集成配置。本文以Logback为例,演示了如何记录不同级别的日志消息,并强调合理配置日志框架对提升系统可靠性和开发效率的重要性。
|
2月前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
60 21
|
2月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
2月前
|
Java 开发者 Spring
理解和解决Spring框架中的事务自调用问题
事务自调用问题是由于 Spring AOP 代理机制引起的,当方法在同一个类内部自调用时,事务注解将失效。通过使用代理对象调用、将事务逻辑分离到不同类中或使用 AspectJ 模式,可以有效解决这一问题。理解和解决这一问题,对于保证 Spring 应用中的事务管理正确性至关重要。掌握这些技巧,可以提高开发效率和代码的健壮性。
127 13