BeanFactory 和 FactoryBean 的区别

本文详细介绍了Spring中的BeanFactory接口及其作用,作为IOC容器的基础,它规定了基本的bean管理和生产。接着讲解了FactoryBean接口,用于提供更灵活的bean创建方式。通过代码实例展示了FactoryBean如何工作,并且对比了BeanFactory和FactoryBean的区别。最后,通过测试验证了它们在实际应用中的效果。
摘要由CSDN通过智能技术生成

BeanFactory

作用

BeanFactory是IOC最基本的容器,负责生产和管理bean,它为其他具体的IOC容器提供了最基本的规范,例如DefaultListableBeanFactory, XmlBeanFactory, ApplicationContext 等具体的容器都是实现了BeanFactory,再在其基础之上附加了其他的功能。

源码

BeanFactory源码

package org.springframework.beans.factory;  
import org.springframework.beans.BeansException;  
public interface BeanFactory {  
    String FACTORY_BEAN_PREFIX = "&";  
    Object getBean(String name) throws BeansException;  
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;  
    <T> T getBean(Class<T> requiredType) throws BeansException;  
    Object getBean(String name, Object... args) throws BeansException;  
    boolean containsBean(String name);  
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;  
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;  
    boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;  
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;  
    String[] getAliases(String name);  
}  

FactoryBean

作用

FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。

FactoryBean源码

package org.springframework.beans.factory;

public interface FactoryBean<T> {
	
	//自定义创建bean方式
    T getObject() throws Exception;

    //从beanFactory 中获取bean的类型
    Class<?> getObjectType();

	//默认单例
    boolean isSingleton();
}

代码实践一下

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                     http://www.springframework.org/schema/context
                     http://www.springframework.org/schema/context/spring-context-3.0.xsd
                     http://www.springframework.org/schema/aop
                     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                     http://www.springframework.org/schema/tx
                     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <bean id="car" class="cn.test.springbean.factoryBean.Car">
        <property name="name" value="吉利" />
    </bean>

    <bean id="carTwo" class="cn.test.springbean.factoryBean.CarTwo">
        <property name="name" value="吉利" />
    </bean>

    <bean id="carFactoryBean" class="cn.test.springbean.factoryBean.CarFactoryBean">
    </bean>
</beans>

FactoryBean的实现类

package cn.test.springbean.factoryBean;

import org.springframework.beans.factory.FactoryBean;

public class CarFactoryBean implements FactoryBean {

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

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

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

}

Car 类

package cn.test.springbean.factoryBean;

public class Car {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

CarTwo 类

package cn.test.springbean.factoryBean;

public class CarTwo {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}


测试一下

package cn.test.springbean.factoryBean;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class FactoryBeanTest {
    public static void main(String[] args){
        String url = "/WEB-INF/BeanConfig.xml";
        ClassPathXmlApplicationContext cpxa = new ClassPathXmlApplicationContext(url);
        Object car =  cpxa.getBean("carFactoryBean");
        System.out.println(car.getClass().getName());

        ConfigurableListableBeanFactory beanFactory = cpxa.getBeanFactory();
        System.out.println(beanFactory.getType("carFactoryBean"));

        CarFactoryBean factoryBeanPojo= (CarFactoryBean) cpxa.getBean("&carFactoryBean");
        System.out.println(factoryBeanPojo.getClass().getName());
    }
}

打印结果

cn.test.springbean.factoryBean.Car
class cn.test.springbean.factoryBean.CarTwo
cn.test.springbean.factoryBean.CarFactoryBean

BeanFactory和FactoryBean的区别

          BeanFactory和FactoryBean其实没有什么比较性的,只是名称特别接近,BeanFactory是提供了OC容器最基本的形式,给具体的IOC容器的实现提供了规范,FactoryBean可以说为IOC容器中Bean的实现提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,我们可以在getObject()方法中灵活配置。其实在Spring源码中有很多FactoryBean的实现类,要想深入准确的理解FactoryBean,只有去读读Spring源码了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值