BeanFactory 和FactoryBean的区别

一、BeanFactory 和FactoryBean的区别

BeanFactory: 是 IOC 容器,并且提供方法支持外部程序对这些 bean 的访问,在程序启动时 根据传入的参数产生各种类型的 bean,并添加到 IOC容器(实现 BeanFactory 接口的类) 的 singletonObject 属性中。

1、负责生产和管理bean的一个工厂。

2、事IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象的依赖。

3、多种实现:如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,其中XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。

FactoryBean:是个接口,它的实现类首先是个 bean,也存放在 BeanFactory 中。它具有工厂方法的功能,可以让我们自定义Bean的创建过程,并添加到了 IOC容器中的factoryBeanObjectCache 属性中。

二、BeanFactory

BeanFactory源码

public interface BeanFactory {
	
    // factoryBean 的转义标识符。(具体用法后面有介绍)
	String FACTORY_BEAN_PREFIX = "&";
	
    // 根据 name 从容器中拿对应的 bean。
	Object getBean(String name) throws BeansException;
	
    // 根据 name 和 type 从容器中拿对应的 bean,要对 bean 的类型做校验。
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
	
    // 在容器中能否找到与 name 匹配的 bean 或者 beanDefinition。
	boolean containsBean(String name);

	// 判断 name 对对应的 bean 是不是 单例。
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
	
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
	// 判断 name 对应的 bean 与指定的类型是否匹配。
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

	//根据 name 获取对应的 bean 的类型。
	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;

    // 根据 name 获取对应 bean 的 别名。
	String[] getAliases(String name);
}

使用场景通过ApplicationContext实现类调用getBean()方法从IOC容器中获取bean

三、FactoryBean

FactoryBean源码

public interface FactoryBean<T> {
	
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
    
	//自定义创建bean方式
	@Nullable
	T getObject() throws Exception;

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

	//默认单例
	default boolean isSingleton() {
		return true;
	}
    
}

四、如何使用FactoryBean接口

创建FactoryBean 的实现类MyFactoryBean ,并使用@Service注解放入IOC容器中

@Service
public class MyFactoryBean implements FactoryBean {


    @Override
    public Object getObject() throws Exception {
		//手动创建bean
        return new PersonServiceImpl();
    }

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

	//这个方法可以不用覆写,父类默认是单例,如果想设置成非单例可以覆写方法返回false
    public boolean isSingleton() {
        return false;
    }
}

创建PersonServiceImpl类,这里我们没有使用@Service注解,说明应用启动时不会放入IOS容器中

public class PersonServiceImpl implements PersonService{

    public void test() {
        System.out.println("3333333");
    }
}
@SpringBootTest
class DemoApplicationTests {

    @Autowired
    ApplicationContext applicationContext;

    @Test
    void test() {
        PersonService bean = applicationContext.getBean(PersonService.class);
        System.out.println(bean);
        bean.test();
        PersonService bean2 = applicationContext.getBean(PersonService.class);
        System.out.println(bean2);
    }

}

编写测试类通过applicationContext的getBean()方法从容器中获取PersonService的bean,发现可以获取到,说明获取bean时发现容器中存在FactoryBean 的实现类MyFactoryBean 并判断传入的类型是否是PersonService如果一样,则返回getObject()方法对象。 这里我们调用了两次bean是不一样的,说明我们设置成了非单例模式
BeanFactory 和FactoryBean的区别_第1张图片

你可能感兴趣的:(spring,java,开发语言)