大家都知道可以通过spring的xml文件的形式来管理Bean,通常情况下,比如有一个类叫做com.athena.beans.MyBean,那么我们可以在xml文件中这样配置:
<bean id="myBean" class="com.athena.beans.MyBean">然后在需要使用该Bean的java类中,可以使用@Resource等注解来让Spring帮助注入该Bean的实例。
一般,通过bean节点配置后生成的实例都是class属性值中类的一个对象,也就是说上面配饰的MyBean,在生成后的实例,肯定是MyBean类型的。
但有下面的一个配置让我很迷茫:
<bean id="properties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="location" value="classpath:prop.properties"/> </bean>看到,上面的class属性中的类是:
PropertiesFactoryBean
而生成的类型却是:Properties类型,它的使用代码如下:
@Resource private Properties properties;
而我原以为应该这样使用:
@Resource private PropertiesFactoryBean properties;也就是说,properties的类型应该是在xml中配置时候的class值的类型才对。。。
但实际使用的时候会报错,只有当把它声明为Properties类型的时候才正确。。。。
我知道可能是Spring对于FactoryBean这样的类可能有特殊处理,但不知道是如何实现的,求讲解,求思路!
多谢
自己顶一下。。求解释
如果容器发现一个beanclass是一个FactoryBean实现类,他仍然会是实例化这个FactoryBean,对他进行注入,但实际的bean对象则是是由这个FactoryBean实例来创建,除了创建实例的方法,FactoryBean本身有方法返回他创建的实例的类型和表示创建的实例是否是单例。
更多细节,建议你在自己实现的FactoryBean里面打上断点调试,沿着调用栈查看Spring的源代码比口头问好很多。
回复<aclass='referer'target='_blank'>@雅典娜拉:eclipse上,FactoryBean的那三个方法随便一个查他们的调用者就有结果了...刚才怕他是反射所以说要debug,结果直接调用就更省事了回复<aclass='referer'target='_blank'>@逝水fox:额,,,好厉害,,,能告诉我你是从哪个类开始找起的么?回复<aclass='referer'target='_blank'>@雅典娜拉:其实用IDE的话很好找的,调试都不需要"iif(beanInstanceinstanceofFactoryBean&&!isFactoryType){"org.springframework.beans.factory.support.StaticListableBeanFactory的代码里面回复<aclass='referer'target='_blank'>@逝水fox:恩,好吧,我试试,不过它的类结构很复杂。。。不过你也为我提供了一种新的思路,多谢指点回复<aclass='referer'target='_blank'>@雅典娜拉:你问的是Spring的实现细节,觉得他是特殊处理,那就打断点调试看什么东西调用你的FactoryBean来生成bean实例的,再在周围找找就会找到特殊处理的证据,细节这些东西看别人说还不如自己看源代码调试看得明白。<preclass="brush:java;toolbar:true;auto-links:false;">publicclassPropertiesFactoryBeanextendsPropertiesLoaderSupportimplementsFactoryBean<Properties>,InitializingBean<imgsrc="http://www.oschina.net/js/ke/plugins/emoticons/images/28.gif"alt=""/>我也说不清楚等别人解答应该是做特殊处理了。返回的时候都给的是<spanstyle="background-color:#F6F6F6;font-family:'CourierNew',Arial;font-size:9pt;line-height:1.5;">Properties
<preclass="brush:java;toolbar:true;auto-links:false;">publicclassPropertiesFactoryBeanextendsPropertiesLoaderSupportimplementsFactoryBean<Properties>,InitializingBean{privatebooleansingleton=true;privatePropertiessingletonInstance;<preclass="brush:java;toolbar:true;auto-links:false;">publicClass<Properties>getObjectType(){returnProperties.class;}不要一味的套规则,要理解原理,你可以去了解下spring的bean创建方式,我个人理解的也许和别人常说的pring的bean几种创建方式可能不一样,我理解的有三种方式
1、构造方法
2、工厂bean(静态方法、实例方法、FactoryBean接口)
3、代理(使用jdk代理或者类似CGlib库。例如:事务处理,spring通过aop方式产生bean的代理对象)
这样子说不定能得到~之所以叫FactoryBean,就因为是用它来生成Bean的,默认情况下,如果一个Bean是FactoryBean,Spring是会返回其生成的Bean,而不是工厂本身,如果想要得到工厂本身,需要在ID前加&.
上面这样子不知道行不行,但<spanstyle="font-family:Helvetica,Tahoma,Arial,sans-serif;font-size:14px;line-height:25.1875px;background-color:#FFFFFF;">factory.getBean('&properteis')应该是可以获取到FactoryBean的。
一般也很少会用到FactoryBean。
这样子说不定能得到~之所以叫FactoryBean,就因为是用它来生成Bean的,默认情况下,如果一个Bean是FactoryBean,Spring是会返回其生成的Bean,而不是工厂本身,如果想要得到工厂本身,需要在ID前加&.
上面这样子不知道行不行,但<spanstyle="font-family:Helvetica,Tahoma,Arial,sans-serif;font-size:14px;line-height:25.1875px;background-color:#FFFFFF;">factory.getBean('&properteis')应该是可以获取到FactoryBean的。
一般也很少会用到FactoryBean。
<arel="nofollow">http://wenku.baidu.com/link?url=N0nQvLfRJ2w-InrUHOiXL_dvl5ecsxg0k7GCH6Eh8EEBCYAGQyyU3-tJ8Qwt21VLD3VJxHVLCKppopIVZGGH4yCNPcNJnfqgV09oNTWiLbG
这个文章可以帮助你理解的!!!
谢谢版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。