Announcement Announcement Module
Collapse
No announcement yet.
FactoryBean and prototype Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • FactoryBean and prototype

    Hi,

    I'm trying to launch a scheduled job that exports some data into files.
    The file name represents the date at which the job has been launched (classical stuff) : 2007-08-06-12-30 for example.

    To do that, I use a FactoryBean that should return a new object which will be the target for a method invocation done by the scheduler.

    Here's my application context snippet :

    Code:
    [...]
        <bean id="csvExporter"
              class="foo.bar.CsvExporterFactoryBean"
              scope="prototype">
            <property name="dirname">
                <value>${export.csv.dir}</value>
            </property>
            <property name="extension">
                <value>${export.csv.extension}</value>
            </property>
            <property name="datePattern">
                <value>${export.csv.date.pattern}</value>
            </property>
            <property name="numberOfDays">
                <value>15</value>
            </property>
            <property name="facade">
                <ref bean="serviceFacade"/>
            </property>
        </bean>
    
        <bean id="csvExporterJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
            <property name="targetObject">
                <ref bean="csvExporter"/>
            </property>
            <property name="targetMethod">
                <value>exportData</value>
            </property>
        </bean>
    
        <bean id="csvExportTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
            <property name="jobDetail">
                <ref bean="csvExporterJob"/>
            </property>
            <property name="cronExpression">
                <value>0 * * * * ?</value>
            </property>
        </bean>
    
        <!-- Schedulers -->
        <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref bean="csvExportTrigger"/>
                </list>
            </property>
        </bean>
    [...]
    And here's my factory bean's code :
    Code:
    public class CsvExporterFactoryBean implements FactoryBean {
        // properties here ...
    
        public CsvExporterFactoryBean() {}
    
        public Object getObject() throws Exception {
            CsvExporter exporter = new CsvExporter();
            // Doing some stuff to determine export file full name ...
            return exporter;
        }
    
        public Class getObjectType() {
            return CsvExporter.class;
        }
    
        public boolean isSingleton() {
            return false;
        }
        
        // Setters and getters
    As you can see, the method isSingleton returns false, but that doesn't prevent the filename to be the same each time, even if the date is different (note : the code is not incriminated, I've tested it thoroughly).

    So I've tried to change the scope of the factory bean to prototype but it doesn't change anything.

    So, my question is : What did I do wrong ?

  • #2
    It is a FAQ question - if a bean is a prototype new bean is created each time when bean is fetched from context. BUT, in your case cvsExporter is fetched from context once only - when it is injected into cvsExporterJob and this is done once only at the moment of the cvsExporterJob creation.

    Spring does not supply you with new cvsExporter each time when you access targetObject property of the cvsExporterJob, first of all Spring does not control this access.

    Please, take look in the Spring reference for further clarifications.

    Regards,
    Oleksandr

    Originally posted by bdusauso View Post
    Hi,

    I'm trying to launch a scheduled job that exports some data into files.
    The file name represents the date at which the job has been launched (classical stuff) : 2007-08-06-12-30 for example.

    To do that, I use a FactoryBean that should return a new object which will be the target for a method invocation done by the scheduler.

    Here's my application context snippet :

    Code:
    [...]
        <bean id="csvExporter"
              class="foo.bar.CsvExporterFactoryBean"
              scope="prototype">
            <property name="dirname">
                <value>${export.csv.dir}</value>
            </property>
            <property name="extension">
                <value>${export.csv.extension}</value>
            </property>
            <property name="datePattern">
                <value>${export.csv.date.pattern}</value>
            </property>
            <property name="numberOfDays">
                <value>15</value>
            </property>
            <property name="facade">
                <ref bean="serviceFacade"/>
            </property>
        </bean>
    
        <bean id="csvExporterJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
            <property name="targetObject">
                <ref bean="csvExporter"/>
            </property>
            <property name="targetMethod">
                <value>exportData</value>
            </property>
        </bean>
    
        <bean id="csvExportTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
            <property name="jobDetail">
                <ref bean="csvExporterJob"/>
            </property>
            <property name="cronExpression">
                <value>0 * * * * ?</value>
            </property>
        </bean>
    
        <!-- Schedulers -->
        <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref bean="csvExportTrigger"/>
                </list>
            </property>
        </bean>
    [...]
    And here's my factory bean's code :
    Code:
    public class CsvExporterFactoryBean implements FactoryBean {
        // properties here ...
    
        public CsvExporterFactoryBean() {}
    
        public Object getObject() throws Exception {
            CsvExporter exporter = new CsvExporter();
            // Doing some stuff to determine export file full name ...
            return exporter;
        }
    
        public Class getObjectType() {
            return CsvExporter.class;
        }
    
        public boolean isSingleton() {
            return false;
        }
        
        // Setters and getters
    As you can see, the method isSingleton returns false, but that doesn't prevent the filename to be the same each time, even if the date is different (note : the code is not incriminated, I've tested it thoroughly).

    So I've tried to change the scope of the factory bean to prototype but it doesn't change anything.

    So, my question is : What did I do wrong ?

    Comment


    • #3
      Originally posted by al0 View Post
      It is a FAQ question [...]
      Ooops ... sorry, I had to RTFM further ..

      Comment


      • #4
        Originally posted by bdusauso View Post
        Ooops ... sorry, I had to RTFM further ..
        To be honest, I'm not 100% sure if it is covered in the FAQ (or ever if FAQ exists at all), but at least it is covered in details in the Spring Reference and was discussed here many, many times.

        Regards,
        Oleksandr

        Comment

        Working...
        X