Can spring create another instance of bean after another bean has completed init?

there is a utility class that needs to reference bean

@Component
class FooUtils implements InitializingBean {
    private static Foo foo;
    private static Bar bar;

    @Autowired
    private void foo(Foo foo) {
        MyFactory.foo = foo;
    }    

    @Override
    public void afterPropertiesSet() throws Exception {
        bar = new Bar(foo, ...);
    }
    
    public static MyObj create(int param1, int param2, int param3) {
        if (foo == null) { thrown new Exception(); }
        return new MyObj(foo.baz(param1, param2), bar, param3);
    }
}

want to create bean with the utility class above

@Configuration
@DependsOn("fooUtils") // <-- work, newbeaninit
class Config {
    @Bean
    public MyObj myObjBean() {
        return FooUtils.create(1, 2, 3); // <-- fooUtilsautowired
    }
}
@Service
class MyService {
    @Autowired
    private MyObj myObj;
}
Jun.12,2021

take a look at spring's comments on DependsOn comments, which I'll list here.


/**
 * 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.
 *
 * 

May be used on any class directly or indirectly annotated with * {@link org.springframework.stereotype.Component} or on methods annotated * with {@link Bean}. * *

Using {@link DependsOn} at the class level has no effect unless component-scanning * is being used. If a {@link DependsOn}-annotated class is declared via XML, * {@link DependsOn} annotation metadata is ignored, and * {@code <bean depends-on="..."/>} is respected instead. * * @author Juergen Hoeller * @since 3.0 */ @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DependsOn { String[] value() default {}; }

did you notice one of the words?

Using {@ link DependsOn} at the class level has no effect unless component-scanning
s being used.

if used on a class, the class needs to be annotated with @ ComponentScan ("xxxxx").


change create to instance method

 

you write like this is equivalent to creating a Bean: fooUtils , but you call FooUtils , these two are not the same instance.

how to solve it.

  1. change the call to fooUtils
  2. use getBean in the create method of FooUtils to get the Bean you want to use
  3. change the way you implement the tool class to avoid referencing Bean in the tool class
Menu