Announcement Announcement Module
Collapse
No announcement yet.
lazy-init ignored for singleton bean Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • lazy-init ignored for singleton bean

    Hi all,

    It seems like the lazy-init attribute on a singleton bean is ignored when the org.springframework.jmx.export.MBeanExporter is used to expose it as a MBean. I've added an init-method for the singleton bean but it is called during start-up if it is exposed as MBean. I thought this is not suppose to happen as lazy-init should be honored according to the documentation. Is this a configuration issue?

    Thanks.

  • #2
    Is the bean used by any other bean or retrieved from the bean factory somewhere else? Perhaps you should turn on debugging information to make sure the object is being lazy initialized. Does the object have any interfaces? If not perhaps CGLIB is required to proxy the object for lazy initialization.

    Comment


    • #3
      This bean works as expected if not exposed as MBean. That is, the init method is called only after the bean is referenced. However, if the bean is exposed as MBean, the init method is called when the appliction context is created. Currently, the bean has two interfances.

      Comment


      • #4
        Can you set a breakpoint in your init method? Perhaps your JMX server is scanning all of its beans at startup, which would instantiate the bean.

        Other than that I can't think of anything. What version of Spring are you using? I've looked at the 1.2.8 version of MBeanExporter and looks like its doing the right thing.

        Comment


        • #5
          This is the stacktrace at the time the initialize() function is called:

          TestService.initialize() line: 10
          NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]
          NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available
          DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available
          Method.invoke(Object, Object...) line: not available
          DefaultListableBeanFactory(AbstractAutowireCapable BeanFactory).invokeCustomInitMethod(String, Object, String, boolean) line: 999
          DefaultListableBeanFactory(AbstractAutowireCapable BeanFactory).invokeInitMethods(String, Object, RootBeanDefinition) line: 961
          DefaultListableBeanFactory(AbstractAutowireCapable BeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 924
          DefaultListableBeanFactory(AbstractAutowireCapable BeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 415
          AbstractBeanFactory$1.getObject() line: 245
          DefaultListableBeanFactory(DefaultSingletonBeanReg istry).getSingleton(String, ObjectFactory) line: 141
          DefaultListableBeanFactory(AbstractBeanFactory).ge tBean(String, Class, Object[]) line: 242
          DefaultListableBeanFactory(AbstractBeanFactory).ge tBean(String) line: 156
          BeanDefinitionValueResolver.resolveReference(Strin g, RuntimeBeanReference) line: 246
          BeanDefinitionValueResolver.resolveValueIfNecessar y(String, Object) line: 128
          BeanDefinitionValueResolver.resolveManagedMap(Stri ng, Map) line: 299
          BeanDefinitionValueResolver.resolveValueIfNecessar y(String, Object) line: 140
          DefaultListableBeanFactory(AbstractAutowireCapable BeanFactory).applyPropertyValues(String, RootBeanDefinition, BeanWrapper, PropertyValues) line: 850
          DefaultListableBeanFactory(AbstractAutowireCapable BeanFactory).populateBean(String, RootBeanDefinition, BeanWrapper) line: 624
          DefaultListableBeanFactory(AbstractAutowireCapable BeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 411
          AbstractBeanFactory$1.getObject() line: 245
          DefaultListableBeanFactory(DefaultSingletonBeanReg istry).getSingleton(String, ObjectFactory) line: 141
          DefaultListableBeanFactory(AbstractBeanFactory).ge tBean(String, Class, Object[]) line: 242DefaultListableBeanFactory(AbstractBeanFactory) .getBean(String) line: 156
          DefaultListableBeanFactory.preInstantiateSingleton s() line: 304
          ClassPathXmlApplicationContext(AbstractApplication Context).refresh() line: 348
          ClassPathXmlApplicationContext.<init>(String[], ApplicationContext) line: 92
          ClassPathXmlApplicationContext.<init>(String[]) line: 77
          ClassPathXmlApplicationContext.<init>(String) line: 68
          Main.main(String[]) line: 11

          with the following Spring configuration file (test.xml):

          <?xml version="1.0" encoding="UTF-8"?>

          <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
          default-init-method="initialize" default-destroy-method="shutdown" default-lazy-init="true" default-autowire="no">

          <bean id="testService" class = "TestService" lazy-init="true">
          <property name="foo" value="100"/>
          </bean>

          <bean id="exporter" class="org.springframework.jmx.export.MBeanExporte r" lazy-init="false">
          <property name="beans">
          <map>
          <entry key="bean:name=testService">
          <ref bean="testService"/>
          </entry>
          </map>
          </property>
          </bean>
          </beans>

          I am using Spring-2.0 RC4 and running Java 1.5 standalone with -Dcom.sun.management.jmxremote

          Comment


          • #6
            You need to use beanNames when referring to objects. According to the MBeanExporter#setBeans javadoc:
            Bean names will be resolved as beans in the current factory, respecting lazy-init markers (that is, not triggering initialization of such beans).
            To fix this change:

            Code:
            <map>
              <entry key="bean:name=testService">
                <ref bean="testService"/>
              </entry>
            </map>
            To:
            Code:
            <map>
              <entry key="bean:name=testService">
                <idref local="testService"/>
              </entry>
            </map>
            This is because the map reference to a bean automatically instantiates it. This is done before the MBeanExporter does it magic with lazy-init.

            Comment


            • #7
              Thanks Bill. That did it and is working as expected.

              Comment

              Working...
              X