Announcement Announcement Module
Collapse
No announcement yet.
lazy init behavior changed in Spring 3.0 vs 2.5? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • lazy init behavior changed in Spring 3.0 vs 2.5?

    We recently upgraded from Spring 2.5.6 to Spring 3.0.2. We had "default-lazy-init" set to true for the majority of the beans and didn't change those settings with our Spring upgrade. However, we found that the lazy-init behavior changed between Spring 2.5 and 3.0.

    Below are the debug logs from running various test cases. Blue lines are custom debug statements, the rest are Spring debug statements.

    As we can see,

    With 2.5, the beans flagged for lazy-init are truely lazily initialized, i.e. they are intialized on demand after the Spring Application Context instantiation is complete.

    With 3.0, the Spring container attempted to eargerly initiate all beans including the ones flagged for lazy-init, as part of the Spring Application Context instantiation step. If any bean flagged for lazy-init throws exception during initialization, the exception will be ignored and Spring Application Context instantiation will continue on.

    This changed lazy-init behavior with 3.0 is kind of acceptable, in the sense that initialization errors of beans flagged for lazy-init may not cause Spring Application Context instantiation to fail (hopefully), but the lazy initialization is not truly lazy anymore. We set the beans to be lazily initialized, because many of them will make connection to backend server as part of bean initialization step, we certainly don't want any single connection failure to prevent the whole Spring container from starting up.

    Is there a reason why lazy-init behavior has changed? Is there a way to make Spring 3.0 lazy-init behave like 2.5?

    Test#1: (2.5) all beans have lazy-init set to true, Spring Context instantiation completes first, a request on BOS.beanX causes BOS.beanX and its dependency BOS.beanA to initialize and they are initialized successfully
    Code:
    ...
    Number of miliseconds taken in initializing my Spring Context:5219
    ...
    Invoking init method  'initialize' on bean with name 'BOS.beanA'
    ...
    Invoking init method  'initialize' on bean with name 'BOS.beanX'
    Test#2: (2.5) all beans have lazy-init set to true, Spring Context instantiation completes first, a request on BOS.beanX causes BOS.beanA to initialize, here we deliberately make BOS.beanA initialization to fail
    Code:
    ...
    Number of miliseconds taken in initializing my Spring Context:4704
    ...
    Invoking init method  'initialize' on bean with name 'BOS.beanA'
    com.abc.exceptions.MyException: java.lang.Exception: this is a test exception in bean initialization
    Test#3: (3.0) all beans have lazy-init set to true, however, Spring initializes all beans eagerly, and successfully
    Code:
    ...
    Invoking init method  'initialize' on bean with name 'BOS.beanA'
    ...
    Invoking init method  'initialize' on bean with name 'BOS.beanX'
    ...
    Invoking init method  'initialize' on bean with name 'BOS.beanY'
    ...
    Number of miliseconds taken in initializing my Spring Context:7110
    Test#4: (3.0) all beans have lazy-init set to true, however, Spring attempts to eagerly initialize all beans, BOS.beanX and BOS.beanY fail to initialize due to initialization failure of their dependency bean BOS.beanA, still, Application Context instantiation is complete, a reqeust on BOS.beanX causes BOS.beanA to initialize again (since the first attempt fails), and it again fails
    Code:
    ...
    Invoking init method  'initialize' on bean with name 'BOS.beanA'
    ...
    Ignoring bean creation exception on FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'BOS.beanX' defined in URL [jar:file:...spring_config.xml]: Cannot resolve reference to bean bean 'BOS.beanA' while setting bean property 'a'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'BOS.beanA' defined in file ...spring_config.xml]: Invocation of init method failed; nested exception is java.lang.Exception: this is a test exception in bean initialization
    ...
    Invoking init method  'initialize' on bean with name 'BOS.beanA'
    ...
    Ignoring bean creation exception on FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'BOS.beanY' defined in URL [jar:file:...spring_config.xml]: Cannot resolve reference to bean bean 'BOS.beanA' while setting bean property 'a'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'BOS.beanA' defined in file ...spring_config.xml]: Invocation of init method failed; nested exception is java.lang.Exception: this is a test exception in bean initialization
    ...
    Number of miliseconds taken in initializing my Spring Context:5609
    ...
    Invoking init method  'initialize' on bean with name 'BOS.beanA'
    com.abc.exceptions.MyException: java.lang.Exception: this is a test exception in bean initialization

  • #2
    I think we are experiencing something similar.

    When we want a bean to be lazily loaded, Spring goes and does a Class.forName for the bean classes eagerly, which causes issues since we have multiple applications using the same application context, but each application does not have access to the applications classes, so we end up with java.lang.ClassNotFoundException Exceptions.

    To get around this, we had to create a proxy factory object which exists in all the applications - not ideal but it is a workaround.

    Does anybody know why the beans are configured like this and whether spring is planning to change this behaviour?

    Thanks

    Comment

    Working...
    X