静下心来的个人专栏
上一篇

使用@ComponentScan 和过滤器进行类路径扫描

广告
选中文字可对指定文章内容进行评论啦,→和←可快速切换按钮,绿色背景文字可以点击查看评论额。
大纲

使用@ComponentScan 和过滤器进行类路径扫描

简介

类路径扫描基本上意味着,检测指定包下需要由 Spring 管理的类。您需要使用带有@Configuration 的spring @ComponentScan 注释进行类路径扫描。此注解允许您指定基本包和过滤器(如果需要精细控制包扫描)。我们将在本文中研究这两种方法。

深入看@ComponentScan注解

在学习使用这个注解之前,我们先来看看这个注解,了解它接受的参数。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
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;
    /**
     * Indicates whether automatic detection of classes annotated with 
     * {@code @Component} {@code @Repository}, {@code @Service}, 
     * or {@code @Controller} should be enabled.
     */
    boolean useDefaultFilters() default true;
    Filter[] includeFilters() default {};
    Filter[] excludeFilters() default {};
    boolean lazyInit() default false;
}

我们将探索其中的每一个,将使用 @ComponentScan 而不指定 basePackages 值,然后将其与基本包参数值一起使用。在此之后,我们还将学习使用自定义过滤器。

使用@ComponentScan 注解

@ComponentScan 可以与 XML <context:component-scan base-package=""/> 配置一起使用。

将 @ComponentScan 与参数一起使用

使用此注解的简单方法是将其与 @Configuration 或应用程序配置类一起使用,并在其中指定基本包。

package basic.ioc.autowire;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import java.util.Random;
import java.util.UUID;
@Configuration
@ComponentScan("basic.ioc.autowire")
public class AutowireBeanConfig {
   //Other configs inside.
}

也可以提供如下所示的基类列表。

@Configuration
@ComponentScan(basePackages = {"basic.ioc.autowire", "basic.ioc.setter"})
public class AutowireBeanConfig {
  //other configs
}

使用不带参数的 @ComponentScan

如前所述,指定 basePackage 值是可选的。不带参数使用时,您对包扫描的控制将减少。

@Configuration
@ComponentScan
public class DemoAppConfig {
    //...
}

注意:@ComponentScan 的放置位置,默认从其包开始扫描。

在 Spring-Boot 应用程序中使用 @ComponentScan

在 Spring-Boot 应用程序中,我们不需要指定 @Configuration 注解,除非我们想要更多地控制类路径扫描。这是因为 @SpringBootApplication 已经是下面列出的三个注释的组合。

@Configuration
@EnableAutoConfiguration
@ComponentScan

在典型的 Spring-Boot 应用程序中,@SpringBootApplication 注释存在于基础级别的包中,因此该包下的所有内容都会被自动检测到。

使用带有 @ComponentScan 的过滤器

@ComponentScan 中的默认过滤器有效地检测原型注解——@Component、@Repository、@Service、@Controller、@RestController 和元注解@Configuration。也可以禁用此默认过滤器,如下所示。

@ComponentScan(basePackages = "com.jbd.app", useDefaultFilters=false)

假设我们要禁用对 @Repository 注释类的检测,但包含名称中包含 Dao 的类,例如学生Dao。

@Configuration
@ComponentScan(basePackages = "com.jbd",
        includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Dao"),
        excludeFilters = @Filter(Repository.class))
public class AppConfig {
    ...
}

在基于 XML 的配置中也可以有相同的配置。

<beans>
    <context:component-scan base-package="com.jbd">
        <context:include-filter type="regex"
                expression=".*Dao"/>
        <context:exclude-filter type="annotation"
                expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>
</beans>

总结

我已经解释了在 Spring 中使用 @ComponentScan 注释自动扫描类并将它们作为 bean 管理的方法。

 

版权声明:著作权归作者所有。

X

欢迎加群学习交流

联系我们