FactoryBean在XML中的依赖注入方法

     最近在探索Quartz的定时任务以数据库方式进行存储获取,其中用到了Spring的MethodInvokingJobDetailFactoryBean。在注入MethodInvokingJobDetailFactoryBean的时候,发现总是出现异常参数的错误。

     

Caused by: java.lang.IllegalArgumentException: Cannot convert value of type [org.quartz.JobDetail] to required type [org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean] for property 'fileTypeJobDetailFactoryBean': no matching editors or conversion strategy found
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:231)
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:138)
	at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:386)
	... 33 more

    原因是MethodInvokingJobDetailFactoryBean实现了FactoryBean的接口,而FactoryBean在Spring进行注入的时候,使用的是FactoryBean的getObject()方法,而不是把FactoryBean自身的实例进行注入。查找了FactoryBean自身的说明也没有找到相关解决办法。

       上网搜索终于找到了解决办法,那就是使用【&】符号,如果需要注入FactoryBean的实例时,使用&beanName进行注入即可,这个在ApplicationContext的getBean方法中使用是没有问题的,但是在XML中使用就会报出来这样的错误。

Caused by: org.xml.sax.SAXParseException: The reference to entity "XXXXXXXX" must end with the ';' delimiter.
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:174)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:388)
	at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1414)
	at com.sun.org.apache.xerces.internal.impl.XMLScanner.scanAttributeValue(XMLScanner.java:868)

  这样的话,就需要进行转义,所以在XML中就需要写成这样&beanName,这样的话,FactoryBean就可以顺利注入了。

      另外回答中也提到了是参考Spring的官方文档【 Customizing instantiation logic using FactoryBeans】,我把关键的地方用红字进行了标注。

       http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-extension-factorybean

   

       

3.7.3. Customizing instantiation logic using FactoryBeans

 

The org.springframework.beans.factory.FactoryBean interface is to be implemented by objects that are themselves factories.

The FactoryBean interface is a point of pluggability into the Spring IoC containers instantiation logic. If you have some complex initialization code that is better expressed in Java as opposed to a (potentially) verbose amount of XML, you can create your own FactoryBean, write the complex initialization inside that class, and then plug your customFactoryBean into the container.

The FactoryBean interface provides three methods:

  • Object getObject(): has to return an instance of the object this factory creates. The instance can possibly be shared (depending on whether this factory returns singletons or prototypes).

  • boolean isSingleton(): has to return true if this FactoryBean returns singletons, false otherwise

  • Class getObjectType(): has to return either the object type returned by the getObject() method or null if the type isn't known in advance

The FactoryBean concept and interface is used in a number of places within the Spring Framework; at the time of writing there are over 50 implementations of the FactoryBeaninterface that ship with Spring itself.

Finally, there is sometimes a need to ask a container for an actual FactoryBean instance itself, not the bean it produces. This may be achieved by prepending the bean id with '&'(sans quotes) when calling the getBean method of the BeanFactory (including ApplicationContext). So for a given FactoryBean with an id of myBean, invokinggetBean("myBean") on the container will return the product of the FactoryBean, but invoking getBean("&myBean") will return the FactoryBean instance itself.

本文参照:

【Spring: Getting FactoryBean object instead of FactoryBean.getObject()】

http://stackoverflow.com/questions/1655140/spring-getting-factorybean-object-instead-of-factorybean-getobject

posted on 2013-04-01 15:02  南郭先生kaka  阅读(1448)  评论(0编辑  收藏  举报

导航