Spring导入其他sdk包中依赖Spring的组件

参考

参考:https://blog.csdn.net/weixin_41540822/article/details/88852973

背景

A服务引入B服务提供的SDK包中的某个util方法,结果报了NPE
debug发现,B服务util方法依赖Spring注入,由于A服务启动时此类不在Spring Boot的组件扫描范围之内,没能完成util方法的注入导致NPE的发生。

@Configuration等注解的自动注入及@ComponentScan的组件扫描

一、自动注入
在平时使用 Spring Boot 时,常常会使用到@Configuration,@Contoller,@Service,@Component等注解,被添加这些注解的类,在 Spring Boot 启动时,会自动被 Spring 容器管理起来。

二、组件扫描
组件扫描的作用就是:当 Spring Boot 启动时,根据定义的扫描路径,把符合扫描规则的类装配到spring容器中。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
  	// 指定扫描包的位置(同:basePackages 属性),可以是单个路径,也可以是扫描的路径数组
    @AliasFor("basePackages")
    String[] value() default {};
	// 指定扫描包的位置(同:value 属性)
    @AliasFor("value")
    String[] basePackages() default {};
	// 指定具体的扫描的类
    Class<?>[] basePackageClasses() default {};
	// bean的名称的生成器	
    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

    Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;

    ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
	// 控制符合组件检测条件的类文件   默认是包扫描下的  **/*.class
    String resourcePattern() default "**/*.class";
    // 是否开启对@Component,@Repository,@Service,@Controller的类进行检测
    boolean useDefaultFilters() default true;
    // 包含的过滤条件
    // 1. FilterType.ANNOTATION:			按照注解过滤
    // 2. FilterType.ASSIGNABLE_TYPE:	    按照给定的类型
    // 3. FilterType.ASPECTJ:				使用ASPECTJ表达式
    // 4. FilterType.REGEX:					正则
    // 5. FilterType.CUSTOM:				自定义规则
    ComponentScan.Filter[] includeFilters() default {};
    // 排除的过滤条件,用法和includeFilters一样
    ComponentScan.Filter[] excludeFilters() default {};

    boolean lazyInit() default false;

    @Retention(RetentionPolicy.RUNTIME)
    @Target({})
    public @interface Filter {
        FilterType type() default FilterType.ANNOTATION;
        @AliasFor("classes")
        Class<?>[] value() default {};
        @AliasFor("value")
        Class<?>[] classes() default {};
        String[] pattern() default {};
    }
}

@ComponentScan的常用方式如下:

  1. 通过使用value,basePackages属性来指定扫描范围;
  2. 自定扫描路径下边带有@Controller,@Service,@Repository,@Component注解加入Spring容器
  3. 通过includeFilters加入扫描路径下没有以上注解的类加入spring容器
  4. 通过excludeFilters过滤出不用加入spring容器的类
  5. 自定义增加了@Component注解的注解方式

@SpringBootApplication启动类

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration                    // 允许自动配置
@ComponentScan(
    excludeFilters = {@Filter(              // 定义排除规则
    type = FilterType.CUSTOM,               // 采用自定义的方式
    classes = {TypeExcludeFilter.class}     // 自定义实现逻辑
), @Filter(                                 // 同上
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    
    // 为 @EnableAutoConfiguration 添加 exclude 规则
    @AliasFor(
        annotation = EnableAutoConfiguration.class,
        attribute = "exclude"
    )
    Class<?>[] exclude() default {};
    
    // 为 @EnableAutoConfiguration 添加 excludeName 规则
    @AliasFor(
        annotation = EnableAutoConfiguration.class,
        attribute = "excludeName"
    )
    String[] excludeName() default {};
    
    // 为 @ComponentScan 添加 basePackages 规则
    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};

    // 为 @ComponentScan 添加 basePackageClasses 规则
    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};
}

@SpringBootApplication是一个组合注解,也就相当于使用一个@SpringBootApplication可以替代@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan几个注解联合使用。
默认只会扫描当前包路径及其子路径下的文件,并将符合条件的对象注入到容器中管理。

有了@SpringBootApplication,此时如何对@ComponentScan的属性做自定义配置呢?

在@SpringBootApplication注解类中的属性上添加@AliasFor注解,从而实现通过对@SpringBootApplication中的属性进行自定义,达到对对应的注解的属性的自定义。

比如:

@AliasFor(
    annotation = ComponentScan.class,
    attribute = "basePackages"
)
String[] scanBasePackages() default {};

通过对@SpringBootApplication的属性scanBasePackages,实现对@ComponentScan中的属性basePackages进行自定义。

最后解决

@SpringBootApplication(scanBasePackages="com.github.jdkong")
public class SecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SecurityApplication.class,args);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值