BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础行为,负责⽣产和管理Bean的⼀个⼯⼚,具体使⽤它下面的子接口类型,比如ApplicationContext。
此处我们重点分析FactoryBean。Spring中Bean有两种,⼀种是普通Bean,⼀种是工厂Bean(FactoryBean),FactoryBean可以生成某⼀个类型的Bean实例(返回给我们),也就是说我们可以借助于它自定义Bean的创建过程。
FactoryBean是一个接口,源码入下:
// 可以让我们⾃定义Bean的创建过程(完成复杂Bean的定义)
public interface FactoryBean<T> {
@Nullable
// 返回FactoryBean创建的Bean实例,如果isSingleton返回true,则该实例会放到Spring容器的单例对象缓存池中Map
T getObject() throws Exception;
@Nullable
// 返回FactoryBean创建的Bean类型
Class<?> getObjectType();
// 返回作⽤域是否单例
default boolean isSingleton() {
return true;
}
}
示例:
public class Company {
private String name;
private String address;
private Long scale;
//提供get、set方法,重写toString
}
public class CompanyFactoryBean implements FactoryBean<Company> {
private String companyInfo; //公司名称,地址,规模
public void setCompanyInfo(String companyInfo) {
this.companyInfo = companyInfo;
}
@Override
public Company getObject() throws Exception {
Company company = new Company();
String[] split = companyInfo.split(",");
company.setName(split[0]);
company.setAddress(split[1]);
company.setScale(Long.parseLong(split[2]));
return company;
}
@Override
public Class<?> getObjectType() {
return Company.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="false" xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="companyBean" class="com.nanmao.factory.CompanyFactoryBean">
<property name="companyInfo" value="南猫信巷,南京,400"/>
</bean>
</beans>
public class IocXmlTest {
@Test
public void TestIocContainer() {
// 通过读取classpath下面的xml文件来启动容器(xml模式SE应用推荐使用)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Object companyBean = applicationContext.getBean("companyBean");
System.out.println(">>>>companyBean:" + companyBean );
}
}
控制台输出:
>>>>companyBean:Company{name='南猫信巷', address='南京', scale=400}
如果我们就是想获取CompanyFactoryBean对象,而不是getObject()方法的返回对象company的话,我们可以在getBean方法中的形参beanId之前加上&符号。
public class IocXmlTest {
@Test
public void TestIocContainer() {
// 通过读取classpath下面的xml文件来启动容器(xml模式SE应用推荐使用)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Object companyBean = applicationContext.getBean("&companyBean");
System.out.println(">>>>companyBean:" + companyBean );
}
}
控制台输出:
>>>>companyBean:com.nanmao.factory.CompanyFactoryBean@192d3247
Bean创建的三种方式中的静态⽅法和实例化方法和FactoryBean作用类似,FactoryBean使用较多,尤其在Spring框架⼀些组件中会使⽤,还有其他框架和Spring框架整合时使用。