2

I have a bean called SpringUtil, which is

@Component
public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext context = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
        throws BeansException {
        this.context = applicationContext;
    }

    public static <T> T getBean(String beanName) {
        return (T) context.getBean(beanName);
    }

    ...
}

There is another bean which uses SpringUtil in its init method, so it requires that SpringUtil to be loaded as bean before it. I tried @ConditionalOnBean(SpringUtil.class) but it doesn't work. Are there any workaround? or radically, make SpringUtil to be initialized before all other beans.

lily
  • 515
  • 7
  • 20
  • 2
    If it is another bean, then why aren't you simply injecting dependencies in there but use this contraption? When resorting to things like a `SpringContextUtil` you are generally doing the wrong things. – M. Deinum Mar 12 '19 at 14:29

2 Answers2

3

You can autowire your SpringUtil and Spring will manage the dependency:

@Autowired
private SpringUtil util;

Another way is to autowire the setter:

@Autowired
private setSpringUtil(SpringUtil springUtil)
NikNik
  • 2,191
  • 2
  • 15
  • 34
  • It might be better to add a little explanation around _why_ this would work. eg: The question is really talking about one class having a dependency on another, so this is an example of how dependencies can be injected in Spring. Another would be to \@Autowire a setter method, or a constructor, or event to get involved with \@Bean methods in \@Configuration classes. Teach the man to fish... and all that – ptomli Mar 12 '19 at 15:13
  • Thank you for the advice. I will definitely update my answer. – NikNik Mar 12 '19 at 15:25
  • You are right! I was thinking to autowire SpringUtil but I wrote it wrong: private SpringUtil util; In any case, thanks for your constructive comment. – NikNik Mar 12 '19 at 15:37
  • fyi: you can use the @ with the username to talk to somebody, i only knew to undo my vote here because i checked back in. – Nathan Hughes Mar 12 '19 at 16:15
1

The @DependsOn annotation can be used for this purpose.

Annotation Type DependsOn

public @interface DependsOn

Beans on which the current bean depends. Any beans specified are guaranteed to be created by the container before this bean. 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 *.

*emphasys is mine

fantaghirocco
  • 4,761
  • 6
  • 38
  • 48
  • what is its difference with ConditionalOnBean? – lily Mar 12 '19 at 14:30
  • maybe [this](https://stackoverflow.com/questions/50518696/spring-boot-conditionalonbean-annotation) can help; anyway `@ConditionalOnBean` is Spring-Boot specific AFAIK – fantaghirocco Mar 12 '19 at 14:33
  • `@DependsOn` is not meant for cases where a bean has an explicit dependency, but merely where there's an implicit dependency. Since the OP states the 3rd class "uses SpringUtil in its init method", it's an explicit dependency, which should be injected via `@Autowired`, `@Inject` or some other DI mechanism supported by Spring. – ptomli Mar 12 '19 at 15:17
  • @ptomly the above answers the question in order to *force a spring bean to be created after another* when `@Autowired` can't do the job – fantaghirocco Mar 12 '19 at 15:31