被Spring管理的bean可以是直接创建实例,还可以通过工厂模式来进行创建。例如brave的tracing bean定义:
1 <bean id="tracing" class="brave.spring.beans.TracingFactoryBean"> 2 ... 3 <property name="propagationFactory"> 4 <bean id="propagationFactory" class="brave.propagation.ExtraFieldPropagation" 5 factory-method="newFactory"> 6 <constructor-arg index="0"> 7 <util:constant static-field="brave.propagation.B3Propagation.FACTORY" /> 8 </constructor-arg> 9 <constructor-arg index="1"> 10 <list> 11 <value>user-name</value> 12 </list> 13 </constructor-arg> 14 </bean> 15 </property> 16 </bean>
1. Spring的工厂模式获取bean
class + factory-method属性的定义指出了该bean的获取方式是静态工厂模式;
与之类似的是实例工厂模式,在spring中实例化一个类,然后通过factory-bean + facgtory-method的方式来获取bean实例。
1 <bean id="carFactory" class="com.home.factoryMethod.CarInstanceFactory"> 2 ... 3 </bean> 4 <bean id="car4" factory-bean="carFactory" factory-method="getCar"> 5 <constructor-arg value="4"></constructor-arg> 6 </bean>
2. 构造/参数
<constructor-arg index="0">这种写法是通过工厂(静态/动态)构造函数的参数,尽管这里是通过factory-method的方式,并不是传统意义的构造函数,那是确实是构造函数的语义。通过constructor-arg这种声明方式除了可以通过xml中配置来进行实例化,还可以通过编程的方式来构造对象:
1 ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-factoryMethod.xml"); 2 Car car1 = (Car) ctx.getBean("car4");
3. 静态字段的处理
1 <constructor-arg index="0"> 2 <util:constant static-field="brave.propagation.B3Propagation.FACTORY" /> 3 </constructor-arg>
这个写法是为第一个构造函数赋值,util:constant static-field这个语义就是说明FACTORY是B3Propagation里面的静态字段,在进行反射处理的时候需要基于静态字段的处理。
4. util:constant
是spring里面很活跃的处理,尤其是在map,list的定义很方便:
1 <bean id="some1" class="cn.itcast.spring._util.Some"> 2 <property name="val" value="some instance1" /> 3 </bean> 4 <bean id="some2" class="cn.itcast.spring._util.Some"> 5 <property name="val" value="some instance2" /> 6 </bean> 7 <bean id="some3" class="cn.itcast.spring._util.Some"> 8 <property name="val" value="some instance3" /> 9 </bean> 10 <util:list id="strArray"> 11 <value>Hello</value> 12 <value>Welcome</value> 13 </util:list> 14 <util:list id="objArray"> 15 <ref bean="some1" /> 16 <ref bean="some2" /> 17 <ref bean="some3" /> 18 </util:list> 19 <util:list id="list" list-class="java.util.ArrayList"> 20 <ref bean="some1"/> 21 <ref bean="some2" /> 22 <ref bean="some3" /> 23 </util:list> 24 <util:map id="map" map-class="java.util.HashMap" > 25 <entry key="key1" value-ref="some1"/> 26 <entry key="key2" value-ref="some2"/> 27 <entry key="key3" value-ref="some3"/> 28 </util:map> 29 <bean id="someBean" class="cn.itcast.spring._util.SomeBean"> 30 <property name="someStrArray" ref="strArray"/> 31 <property name="someObjArray" ref="objArray"/> 32 <property name="someList" ref="list"/> 33 <property name="someMap" ref="map"/> 34 </bean>
5. Spring里面的sington
一类工厂bean是AbstractFactoryBean,那么可以通过setSingleton来设定创建的类是singleton还是每次都返回新的实例。
参考: