MohammadZoghi
MohammadZoghi

Reputation: 588

Is there a way to call a method in a bean after all spring context is initialized

I have a problem and this is the gist of it: (there are more classes involved in the loop but it can be represented this way)

@service
public class serviceDispatcher{
    @Autowired
    private BeanA a;

    @Autowired
    private BeanB b;

    public BeanA getBeanA(){
        return a;
    }

    public BeanB getBeanB(){
        return b;
    }
}

@Service
public class BeanA{
    @Autowired
    ServiceDispatcher sd;

    @PostConstruct
    private void init(){
        sd.getBeanB().method;
    }
}

so obviously I get a null pointer since BeanB b is not yet resolved. I also used afterPropertiesSet and it is the same. My question is that if there is a way to run the init() method after the whole context is initialized so that I don't get this null pointer? I am aware of the fact that having this circular dependency is trouble and needs to be solved but I'm just refactoring a huge project to use Spring DI and changing the design, logic and business requires a long process of asking it to be done by other teams.

Upvotes: 2

Views: 4443

Answers (3)

Amit
Amit

Reputation: 486

For the class BeanA, add the annotation @DependsOn("beanB")

Upvotes: 0

Bohdan Levchenko
Bohdan Levchenko

Reputation: 3561

You will have to subscribe to ContextRefreshedEvent event in order to execute your code once spring context is full initialized.

@Component
class N51348516 implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        System.out.println(event.getApplicationContext());
    }
}

But I guess what you really need is to make your bean lazy with @Lazy annotation so you will be able to access them correctly.

Upvotes: 4

Merve Sahin
Merve Sahin

Reputation: 1048

I don't understand why you need to use the serviceDispatcher in the first place. You could try to directly inject BeanB into BeanA:

@Service
public class BeanA{
   private BeanB beanB;

   @Autowired
   public BeanA(BeanB b){
      beanB = b;
      beanB.someMethod();
   }
}

Upvotes: 0

Related Questions