前言
本文是博文 《Spring创建bean的各种方法》 的实例补充,创建bean的知识概念可以从上文中看到
目录
一. 测试环境
测试用例使用spring-maven搭建web服务。因此启动服务时,我们默认直接启动spring容器,xml里面配置<load-on-startup>,如下
<!-- 配置spring -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!--默认是:<param-value>/WEB-INF/classes/[servlet-name]-servlet.xml</param-value>-->
<param-value>classpath*:/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
二. XML配置
1. 构造器 +property
基础class是XMLCreateBean,以此类创建bean
package org.create.bean.test;
import org.springframework.beans.factory.BeanNameAware;
public class XMLCreateBean implements BeanNameAware {
private String field;
public XMLCreateBean(String arg) {
field = arg;
}
@Override
public void setBeanName(String name) {
System.out.println(name + " bean创建 , 参数field == " + field);
}
}
xml中配置:
<bean id="xmlBeanConstructor" class="org.create.bean.test.XMLCreateBean">
<constructor-arg value="xml-constructor"/>
</bean>
<bean id="xmlBeanProperty" class="org.create.bean.test.XMLCreateBean">
<constructor-arg value="xml-set"/>
</bean>
启动服务器,可以看到日志结果:
2. 静态工厂方法
基础class还是上面的 XMLCreateBean, static工厂方法如下:
package org.create.bean.test;
public class XMLFactoryMethodBean {
public static XMLCreateBean factoryMethod(String arg) {
return new XMLCreateBean(arg);
}
}
xml配置factory-method如下:
<bean id="xmlFactoryMethod" class="org.create.bean.test.XMLFactoryMethodBean" factory-method="factoryMethod">
<constructor-arg value="xml-factory-bean"/>
</bean>
启动服务,日志结果:
3. 实例方法
基础class还是上面的 XMLCreateBean,实例方法写在XMLFactoryMethodBean 中, 如下:
package org.create.bean.test;
public class XMLFactoryMethodBean {
public static XMLCreateBean factoryMethod(String arg) {
return new XMLCreateBean(arg);
}
public XMLCreateBean beanMethod(String arg) {
return new XMLCreateBean(arg);
}
}
xml配置如下,调用XMLFactoryMethodBean的beanMethod()方法创建了bean:
<bean id="factoryBean" class="org.create.bean.test.XMLFactoryMethodBean"/>
<bean id="xmlBeanMethod" factory-bean="factoryBean" factory-method="beanMethod">
<constructor-arg value="xml-bean-method"/>
</bean>
启动服务,日志结果:
4. FactoryBean
生成bean的class,编写为FactoryBeanImpl ,如下
package org.create.bean.test;
import org.springframework.beans.factory.FactoryBean;
public class FactoryBeanImpl implements FactoryBean<XMLCreateBean> {
@Override
public XMLCreateBean getObject() throws Exception {
return new XMLCreateBean("factoryBean");
}
@Override
public Class getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
可以看到,FactoryBeanImpl 实现了FactoryBean<>的接口;最终要生成的bean,还是 XMLCreateBean。
为了测试,我重新写了一个类AppMain,实现ApplicationContextAware接口,完成从spring容器获取对应bean
package org.create.bean.test;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class AppMain implements ApplicationContextAware{
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
//Spring框架启动,此bean创建完成后,会自动执行下面对代码
XMLCreateBean xmlCreateBean = (XMLCreateBean) applicationContext.getBean("factoryBean__");
System.out.println(xmlCreateBean.getField());;
}
}
xml配置如下
<bean id="factoryBean__" class="org.create.bean.test.FactoryBeanImpl"></bean>
<bean id="appMain" class="org.create.bean.test.AppMain"/>
启动服务,日志结果
我在测试时,发现使用 @Autowired 注解注入FactoryBean方式的bean,会出现类型转换错误或者null的情况,因为@Autowired 是根据byType的方式注入的,可能会出问题。因此最好使用 @Resource(name="XXX")的方式去注入