关于@Autowired字段继承后能否被注入

Background

@Inherited是一种元注解(指的是修饰注解的注解)。注意:

@Inherited修饰的注解(例如@My)只有修饰在上,才会起到所谓的继承作用,修饰字段、方法是不能起到继承作用。
Java注解学习-@Inherited

关于@Autowired

举例说明。现在有父类FatherService,其有个字段TargetService@Autowired修饰;

@Service
public class FatherService {

    @Autowired
    public TargetService targetService;
}

子类SonService继承父类:

@Service
public class SonService extends FatherService{
    
}

测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
@Slf4j
public class SonServiceTest {

    @Autowired
    SonService sonService;

    @Test
    public void test() throws Exception {

        Assert.assertNotEquals(null, sonService.targetService);
    }
}

请问:测试类中的sonService.targetService是否为null
答案是不为null。原因是Spring的AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement.inject会对一个类的本身的字段其所有父类的字段进行遍历,凡是含有@Autowired的字段都会被注入。我用反射方式来近乎实现这个结果:

SonService sonService = new SonService();
// 被注入的bean
TargetService ts = new TargetService(); 
// 获取对象的子类的父类的该字段
Field fatherField = sonService.getClass().getSuperclass().getDeclaredField("targetService");
// 注入
fatherField.set(sonService, ts);

为什么我在第一节提到了@Inherited?我原以为@Autowired是因为被@Inherited修饰过,所以子类才能继承父类的被注入字段。实际上@Inherited是这么用的:

@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface My {
}
@My // 用到类上才可以被子类SonService继承
@Service
public class FatherService {

    @Autowired
    public TargetService targetService;
}

Extension

如果我把上面的子类改为:

@Service
public class SonService extends FatherService{
    public TargetService targetService;
}

实际上这时,sonService有了两个字段:targetService父类的targetService。只不过父类的targetService属于隐形字段(在调用sonService.targetService调用的是targetService)。

你可能感兴趣的:(关于@Autowired字段继承后能否被注入)