博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring-Batch中MapJobExplorerFactoryBean的配置方式
阅读量:6825 次
发布时间:2019-06-26

本文共 5381 字,大约阅读时间需要 17 分钟。

hot3.png

在使用Spring Batch时,JobExplorer作为查询浏览job以及Step的入口,可以方便的让我们及时掌握Batch的执行情况,一般会使用MapJobExplorerFactoryBean,它需要一个MapJobRepositoryFactoryBean属性,在进行xml配置时,如果配置成下面这种情况,会得到一个exception

Caused By: java.lang.IllegalStateException: Cannot convert value of type [$Proxy123 implementing org.springframework.batch.core.repository.JobRepository,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean] for property 'repositoryFactory': no matching editors or conversion strategy found	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:267)	at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:449)	at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:495)	at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:489)	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1465)	Truncated. see log file for complete stacktrace

究其原因, MapJobRepositoryFactoryBean是一个FactoryBean接口的实现,所以在注入到MapJobExplorerFactoryBean时,得到的是getObject()返回的对象实例。

针对这个问题,我们可以将配置改为这种形式:

 

在Spring的官方文档中,关于FactoryBean有这样一段描述,注意这句“When you need to ask a container for an actual FactoryBean instance itself instead of the bean it produces, preface the bean’s id with the ampersand symbol ( &) when calling the getBean() method of the ApplicationContext”,大意是说,当通过getBean()想获得一个FactoryBean对象的实际实例时,可以在它的bean id前加上“&”符号。“&”符号在XML中应转义为&,所以,便有了上面的配置

7.8.3 Customizing instantiation logic with a FactoryBeanImplement the org.springframework.beans.factory.FactoryBean interface for objects that are themselves factories.The FactoryBean interface is a point of pluggability into the Spring IoC container’s instantiation logic. If you have 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 custom FactoryBean into the container.The FactoryBean interface provides three methods:    Object getObject(): returns 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(): returns true if this FactoryBean returns singletons, false otherwise.    Class getObjectType(): returns the object type returned by the getObject() method or null if the type is not known in advance. The FactoryBean concept and interface is used in a number of places within the Spring Framework; more than 50 implementations of the FactoryBean interface ship with Spring itself.When you need to ask a container for an actual FactoryBean instance itself instead of the bean it produces, preface the bean’s id with the ampersand symbol ( &) when calling the getBean() method of the ApplicationContext. So for a given FactoryBean with an id of myBean, invoking getBean("myBean") on the container returns the product of the FactoryBean; whereas, invoking getBean("&myBean") returns the FactoryBean instance itself.

 

另外,通过Spring的源码,也可以看到,对这块逻辑的处理:

protected 
T doGetBean(String name, Class
requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException{ final String beanName = transformedBeanName(name); Object sharedInstance = getSingleton(beanName); Object bean; if ((sharedInstance != null) && (args == null)) { if (this.logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { this.logger.debug(new StringBuilder().append("Returning eagerly cached instance of singleton bean '").append(beanName).append("' that is not fully initialized yet - a consequence of a circular reference").toString()); } else { this.logger.debug(new StringBuilder().append("Returning cached instance of singleton bean '").append(beanName).append("'").toString()); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } //省略....}protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd){ if ((BeanFactoryUtils.isFactoryDereference(name)) && (!(beanInstance instanceof FactoryBean))) { throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); } //BeanFactoryUtils.isFactoryDereference判断name是否以"&"开始,如果以"&"开始 返回true if ((!(beanInstance instanceof FactoryBean)) || (BeanFactoryUtils.isFactoryDereference(name))) { return beanInstance; } Object object = null; if (mbd == null) { object = getCachedObjectForFactoryBean(beanName); } if (object == null) { FactoryBean factory = (FactoryBean)beanInstance; if ((mbd == null) && (containsBeanDefinition(beanName))) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null) && (mbd.isSynthetic()); object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object;}

 

转载于:https://my.oschina.net/JasonZhang/blog/724270

你可能感兴趣的文章
JAVA---JDK环境变量的配置
查看>>
代码规范
查看>>
冒泡排序
查看>>
试试这个博客怎么样
查看>>
nginx静态服务器静态资源发布脚本
查看>>
再流弊的技术,也抵不过一次事故:兼谈技术管理
查看>>
使用PIPESTATUS获取管道中所有命令的返回码
查看>>
CISCO CEF技术浅析
查看>>
API调用的几种类型
查看>>
写在前面2
查看>>
我的友情链接
查看>>
Juniper防火墙中文件安装配置手册
查看>>
react-router 学习笔记
查看>>
tomcat安装配置
查看>>
Struts2.0+Hibernate2.5+Spring3.0搭建JavaEE项目要用的jar
查看>>
Lync Server 2010调整用户设置时,报“访问特权不够”错误解决方法
查看>>
2013互联网公司,年终奖有几何?
查看>>
Linux上安装二进制文件MySQL详解
查看>>
互联网
查看>>
MySQL load data 权限相关
查看>>