khachik
khachik

Reputation: 28703

Spring - catch bean creation exception

I want to catch bean instantiation exceptions in my code. What options do I have? One way to do this is to use Java-based container configuration:

@Configuration
public class AppConfig {
  @Bean
  public SomeBean someBean() {
    try {
      return new SomeBean(); // throws SomeException
    } catch(SomeException se) {
      return new SomeBeanStub();
    }
  }
}

Is that possible to define exception handlers for bean instantiation using Spring using XML-based or annotation-based configuration?

Upvotes: 20

Views: 23925

Answers (4)

Sergey Shcherbakov
Sergey Shcherbakov

Reputation: 4778

In case if you expect failures during bean creation and the bean is not mandatory for the rest of the application (pretty legitimate situation) you can do as you have suggested by catching all failure exceptions in the @Bean method body and returning null to indicate that the bean creation has failed. The bean will not be added to the Spring application context in this case and the context construction will succeed in case if there are no mandatory dependencies on the given bean.

Upvotes: 0

Derek Mahar
Derek Mahar

Reputation: 28386

Method someBean should catch SomeException and then throw BeanCreationException with SomeException as the cause:

@Configuration
public class AppConfig {
  @Bean
  public SomeBean someBean() {
    try {
      return new SomeBean(); // throws SomeException
    } catch (SomeException se) {
      throw new BeanCreationException("someBean", "Failed to create a SomeBean", se);
    }
  }
}

Upvotes: 16

mjspier
mjspier

Reputation: 6536

Just for completeness.

You can also lazy init the bean and catch the exception the first time you use the bean.

spring config:

<bean id="a" class="A" lazy-init="true" />

In java:

import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

public class B {

    @Autowired
    @Lazy
    A a;

    public void foo(){
         try{
               a.foo();
         } catch (BeanCreationException e){
               // ignore if you want
         }
    }
}

Upvotes: 3

Jatin
Jatin

Reputation: 31754

You are not suppose to do that. That is the whole point of having Spring create a bean for you. If you are to create your own beans using new (like above), why use Spring to create beans for you?

You can indeed allocate object for your self and work along instead of dependency injection and all.

Though I understand the essence behind the question. I think it is best if it fails during the server load time. Reason: The application wont be in an inconsistent state. Say suppose you catch the exception and do some cleanliness, but the other classes would be expecting for that bean to exist which it doesn't.

Hence best it fails at initialization so that the application is consistent. Though I do not know of any other legitimate way of doing.

Upvotes: 3

Related Questions