简体   繁体   中英

Why Spring DependsOn annotation cannot use to auto wire an interface

When I'm working on write some spring code, I'm using spring 4 with class and annotation-config. I have declared a bean implements an interface as a component. And I'm trying to make another bean to depends on it with its interface time. But it doesn't work because spring throws an error with no bean found in that name. I think it may because depends on is only work with concretive class auto wire, but I don't know why it set in this way? Is anyone could explain why depends on annotation don't allow type auto wire to an interface?

The simple sample code is like this

@Component
class A implement B{
}

@Component
@DependsOn("B")
class C {
}

the code above cannot work unless I change @DependsOn("B") to @DependsOn("A")

In general DependsOn should never be used. If you ever need to it, you have probably done something wrong, or you have an extreme corner case. I have used Spring since 2006 and have not needed it yet.

The JavaDoc says

Used infrequently in cases where a bean does not explicitly depend on another through properties or constructor arguments, but rather depends on the side effects of another bean's initialization.

This basically means you only use DependsOn if you or some one else have written bad code. For instance one beans constructor creates a resource on disk that another bean needs when constructed. Springs IoC container and declarative wiring lets you control dependencies between beans, but in the extremely rare case where some legacy code has undeclared dependencies DependsOn lets you control the order unrelated spring beans are constructed.

For simple autowiring, use @Autowired either on field or constructor. Starting with Spring 4.3 you can omit the @Autowired when using constructor injection.

@Component
class A implement B {
}

@Component
class C {
    private final B b;

    public C(B b) {
        this.b = b;
    }
}

I had same problem when I tried to used depends on, but after doing my research I found that the best way is to remove the dependency of B in class C constructor and use this logic in a method init annotated by @PostConstruct , so after initializing all the constructors this method will be executed. Hope my answer helps you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM