记一次SpringBoot中Service层未注入排查

    同事自己在自己的电脑上写了一些小东西,遇到了请求时API层注入的Service为空问题。整体代码接口伪代码如下:

public Interface ParentService{
    public String hello(String msg);
}
public abstract class ChildrenOneService implements ParentService{

    @Override
    public String hello(String msg){
        System.out.println("ChildrenOne say"+msg);
    }

}
public abstract class ChildrenTwoService implements ParentService{

    @Override
    public String hello(String msg){
        System.out.println("ChildrenTwo say"+msg);
    }

}

 

@RestController
public class TestApi{
    @Resource(type = ChildrenOneService.class)
    private Parent childrenOneService;

    @Resource(type = ChildrenTwoService.class)
    private Parent childrenTwoService;
    
    @PostMapping("/test1")
    public String sayOne(String msg){
        childrenOneService.hello(msg);
    }

    @PostMapping("/test2")
    public String sayTwo(String msg){
        childrenTwoService.hello(msg);
    }

}

      在执行过程中报空指针异常,打断点发现childrenOneService和childrenTwoService全部为空。直接在AbstractApplicationContext里的refresh方法里最后一行finishRefresh打断点查看beanFactory里的beanDefinitionMap里的bean是否存在。经过排查发现Map里没有这两个类型的Bean。

     第一步:怀疑是Application.java的ComponentScan没有扫描到。

          查看Application.java启动类,发现Application类上没有配置ComponentScan,那么SpringBoot默认扫描Application文件所在同级目录下的所有类。发现ChildrenOneService和ChildrenTwoService在Application文件所在的同级目录下。

    第二步:怀疑是ChildrenOneService和ChildrenTwoService不符合bean的规范。检查这两个类发现这两个类的类定义里使用了abstract关键字来修饰类名。

	protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
		AnnotationMetadata metadata = beanDefinition.getMetadata();
		return (metadata.isIndependent() && (metadata.isConcrete() ||
				(metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
	}

在springboot源码中发现加载时会判断是否时符合要求的组件,其中发现组件是抽象的且被Lookup注解才会被加载。所以在将ChildrenOneService和ChildrenTwoService类由抽象改为普通类后,注入成功了。

改后(以ChildrenOneService为例):

//去掉了abstract
public class ChildrenOneService implements ParentService{

    @Override
    public String hello(String msg){
        System.out.println("ChildrenOne say"+msg);
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值