4

Another day another problem. Such is the life of the programmer.

So I have an interface called DataCleaner that has 5 implementing classes.

4 of these implementing classes are designed to call a clean method on the DAO of its respective domain object. So FooCleaner calls fooDao.clean() etc etc.

The 5th cleaner is annotated @Scheduled and designed to autowire the other 4 in and run them in a specified order (using the @Order annotation on the other 4 implementing classes.

Interface:

public interface DataCleaner {
    public void clean();
}

One of the 4 implementers (They are all essentially the same pattern, only difference is the value inside the @Order annotation, and the different DAO's):

@Component
@Order(value = 3)
public class FooDataCleanerImpl implements DataCleaner {

    @Autowired
    private fooDAO fooDao;

    @Override
    public void clean() {
        fooDao.clean();
    }
}

Scheduled Implementation:

@Component
public class ScheduledDataCleaner implements DataCleaner {

    protected static final Logger logger = LogManager.getLogger(ScheduledDataCleaner.class);
    @Autowired
    private List<DataCleaner> dataCleaners;

    @Override
    @Scheduled(cron="0 58 13 * * *")
    public void clean() {
        for(DataCleaner dataCleaner : dataCleaners){
            logger.info(dataCleaner);
            dataCleaner.clean();
        }
    }
}

To my pleasant surprise the Scheduled cleaner didn't get it's own instance added to the list. To be totally clear I am very glad that this doesn't occur, because it would make my life much harder if I had to ensure that it didn't occur, and to avoid the unresolvable recursive call.

But my question is why doesn't this implementation become a candidate for autowiring? It implements the required interface and it's in the application context. Is Spring doing something very clever in the Bean Factory to determine that it can't be autowired onto itself, or is it just something that Spring can't do to singleton instances, that would happen if it was a prototype instance?

JamesENL
  • 6,400
  • 6
  • 39
  • 64
  • 1
    I'm going to speculate a bit, and say it's because a component that injects a dependency on itself would *always* cause an infinite loop. – Elliott Frisch Feb 05 '15 at 06:21
  • I have a feeling that is on the right track, but I can't find anything in documentation states that that is the case. – JamesENL Feb 05 '15 at 06:22
  • I couldn't either, that's why I said I was speculating. – Elliott Frisch Feb 05 '15 at 06:23
  • hahaha I know, it's a bit of an interesting problem. – JamesENL Feb 05 '15 at 06:24
  • 2
    The [`AutowiredAnnotationBeanPostProcessor`](http://docs.spring.io/spring/docs/3.0.x/api/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html) does say that *Fields are injected right after construction of a bean, before any config methods are invoked. Such a config field does not have to be public.* And again, if the bean tried to inject a copy of itself that would cause infinite recursion. – Elliott Frisch Feb 05 '15 at 06:25
  • gah, of course there is a duplicate question. Cheers for pointing that one out. – JamesENL Feb 05 '15 at 06:29
  • 2
    I had to search the code, find the cause, and reverse lookup for it. Hope it answers everything (that it can). – Sotirios Delimanolis Feb 05 '15 at 06:29
  • Yep it totally does. That makes so much sense. – JamesENL Feb 05 '15 at 06:30

0 Answers0