Surya
Surya

Reputation: 504

Instantiation of Bean through Factory method

I have declared a bean which is instantiated via a factory method. The factory method invokes some remote services. So, the method has been declared to throw Exception.

The bean is correctly being instantiated when everything works fine. However, when the factory method throws exception, then everything starts going wrong. because my declared bean is referenced from another bean.

I want to set a default value, if the factory method throws Exception.

Part of my config file is as follows :

<bean id="Helper" class="com.test.Helper">
   <constructor-arg ref="myBean" />
</bean>
<bean id="myBean" class="com.test.Factory" factory-method="getBean" />

the getBean() method is as follows:

Factory {
      public static Bean getBean() throws Exception{
             //Invokes some Remote Services and does some processing
             ....
             ....
            //returns bean object
      }

  }

Please help me how I can solve this. I am not allowed to modify the factory method.

Upvotes: 1

Views: 5670

Answers (1)

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340743

If bean or factory method throws an exception during creation, the whole application context startup fails (I guess this is what you mean by "everything starts going wrong"). There is nothing you can do about it on the Spring side.

If you want to return some default value, simply catch the exception in your custom factory, log it and return that default. If you cannot modify the existing factory, consider @Configuration approach:

@Configuration
public SafeCfg {

    @org.springframework.context.annotation.Bean
    public Bean bean() {
        try {
            return Factory.getBean();
        } catch(Exception e) {
            return //some default Bean
        }
    }

}

It works since Spring 3.0. Just place it somewhere so that the application context can pick it up.

But I doubt this is what you want. Even when the external system becomes available, you'll be still using the default, fallback value. Do you expect it to work like this? More advanced approach is to use lazy proxy (Spring has support for that: Is there a spring lazy proxy factory in Spring?) and initialize it only when needed and refresh when broken.

Upvotes: 3

Related Questions