BeanFactory和FactoryBean的区别及相关分析

 

我所用的Spring版本是5.0.x的版本

BeanFactory和FactoryBean都是接口

1、BeanFactory

用于访问SpringBean容器的根接口。这是bean容器的基本客户机视图;

由BeanFactory中使用的对象实现的接口,这些对象本身就是单个对象的工厂,直接利用getbean()来获取对应的实例话bean的.

注意:其中BeanFactory的FACTORY_BEAN_PREFIX的属性是利用他来区分BeanFactory和FactoryBean的,如果你想获得这个bean的你需要在bean的名字前面加个"&",你才能获得对应的 FactoryBean的实现bean.

2、FactoryBean

a)如果一个bean实现了这个接口,它将被用作一个要公开的对象的工厂,而不是直接作为一个将要公开的bean实例。

注意:实现此接口的bean不能用作普通bean ,FactoryBean是以bean样式定义的,但是为bean引用公开的对象始终是getObject()创建的对象。

b) 当一个类当他的依赖关系很复杂的时候,而我们需要提供一个简单的依赖关系的时候,让外部更容易取配置的时候,可以使用FactoryBean.经典应用场景就是mybatis的SqlsessionFactoryBean对象

c)如果一个类实现了FactoryBean 那么spring容器当中存在两个对象,一个是getObject()返回的对象,另一个是当前对象 getObject得到的对象存在是当前类指定的名字,实现factoryBean对象是 "&" +当前类的名字

 

 

太抽象不多废话了直接上代码

例1如下:

TempDaoFactoryBean一个普通的bean

public class TempDaoFactoryBean {

    public void  test(){

        System.out.println("TempDaoFactoryBean");
    }
}

DaoFactoryBean是实现了FactoryBean接口

@Component("daoFactoryBean")
public class DaoFactoryBean implements FactoryBean {

    public void testBean(){
        System.out.println("testBean");
    }


    @Override
    public Object getObject() throws Exception {
        return new TempDaoFactoryBean();
    }

    @Override
    public Class<?> getObjectType() {
        return TempDaoFactoryBean.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

3、配置中信息

@Configuration
@ComponentScan("com.lquan")
public class Configration {
}

4、测试类

 

public class Test {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext
                = new AnnotationConfigApplicationContext(Configration.class);

        // 注意获取factorybean的实例对象需要在对应beanname前面加"&"
        DaoFactoryBean daoFactoryBean = (DaoFactoryBean) annotationConfigApplicationContext.getBean("&daoFactoryBean");
        daoFactoryBean.testBean();


        TempDaoFactoryBean tempDaoFactoryBean = (TempDaoFactoryBean) annotationConfigApplicationContext.getBean("daoFactoryBean");
        tempDaoFactoryBean.test();
    }
}

 

测试结果

注意:如果我们像不同类一样来获取factorybean的实例对象的话会报转换异常.

public class Test {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext
                = new AnnotationConfigApplicationContext(Configration.class);

        // 注意获取factorybean的实例对象需要在对应beanname前面不加"&"
        DaoFactoryBean daoFactoryBean = (DaoFactoryBean) annotationConfigApplicationContext.getBean("daoFactoryBean");
        daoFactoryBean.testBean();


    }
}

运行结果:

 

 

FactoryBean的应用

当一个类当他的依赖关系很复杂的时候,而我们需要提供一个简单的依赖关系的时候,让外部更容易取配置的时候,可以使用FactoryBean.经典应用场景就是mybatis的SqlsessionFactoryBean对象.

 

例二:

代码如下:

1、实现了FactoryBean接口的DaoFactoryBean

public class DaoFactoryBean implements FactoryBean {

	private String info;

	public void setInfo(String info) {
		this.info = info;
	}

	public void testBean(){
        System.out.println("testBean");
    }


    @Override
    public Object getObject() throws Exception {
		TempDaoFactoryBean tempDaoFactoryBean = new TempDaoFactoryBean();
		// 统一处理
		String[] infos = info.split(",");
		tempDaoFactoryBean.setMsg1(infos[0]);
		tempDaoFactoryBean.setDesc(infos[1]);
		tempDaoFactoryBean.setAge(infos[2]);
        return tempDaoFactoryBean;
    }

    @Override
    public Class<?> getObjectType() {
        return TempDaoFactoryBean.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

2、普通的类TempDaoFactoryBean

public class TempDaoFactoryBean {

	private String msg1;
	private String desc;
	private String age;


	public String getMsg1() {
		System.out.println(msg1);
		return msg1;
	}

	public void setMsg1(String msg1) {
		this.msg1 = msg1;
	}

	public String getDesc() {
		System.out.println(desc);
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}

	public String getAge() {
		System.out.println(age);
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}

	public void  test(){

        System.out.println("TempDaoFactoryBean");
    }
}

 

3、配置

@Configuration
@ComponentScan("com.lquan.spring.xml")
@ImportResource("classpath:spring.xml")
public class Config {
}

4、spring.xml的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans 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="daoFactoryBean" class="com.lquan.spring.xml.dao.DaoFactoryBean">
		<property name="info" value="你好,12,描述信息"/>
	</bean>

</beans>

运行结果:

 

意义:简化了配置TempDaoFactoryBean在xml中的配置,不然的话就需要在spring配置对应相关的每一条属性like this

<?xml version="1.0" encoding="UTF-8"?>
<beans 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="daoFactoryBean" class="com.lquan.spring.xml.dao.DaoFactoryBean">
		<property name="info" value="你好,12,描述信息"/>
	</bean>
-->

	<bean id="tempDaoFactoryBean" class="com.lquan.spring.xml.dao.TempDaoFactoryBean">
		<property name="desc" value="描述信息"/>
		<property name="age" value="年龄"/>
		<property name="msg1" value="信息压压"/>
	</bean>

</beans>

相比之下利用factoryBean更有利于简化配置,

 

总结区别:

BeanFactory是个 Factory ,也就是 IOC 容器或对象工厂, FactoryBean 是个 Bean 。在 Spring 中,所有的 Bean 都是由 BeanFactory( 也就是 IOC 容器 ) 来进行管理的。但对 FactoryBean 而言,这个 Bean 不是简单的普通Bean ,而是一个能生产或者修饰对象生成的工厂 Bean, 它的实现与设计模式中的工厂模式和修饰器模式类似.

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值