Spring源码之BeanFactory与FactoryBean

All Rights Reserved © jackiegu.cn

文章目录

1. BeanFactory

1.1 BeanFactory介绍

BeanFactory是Spring IOC各种容器的*接口,定义了创建Bean实例的一些行为,以及一些对Bean实例的判断行为和获取Bean类型属性的行为;

1.2 BeanFactory源码

public interface BeanFactory {

    // FactoryBean的实例名称前缀
	String FACTORY_BEAN_PREFIX = "&";

    // 返回name名称的Bean实例(包含创建过程)
	Object getBean(String name) throws BeansException;

	<T> T getBean(String name, Class<T> requiredType) throws BeansException;

	Object getBean(String name, Object... args) throws BeansException;

	<T> T getBean(Class<T> requiredType) throws BeansException;

	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

    // 返回name名称的Bean实例的提供程序
	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

    // 判断name名称Bean实例的相关属性
	boolean containsBean(String name);

	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

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

    // 返回name名称Bean实例的Class类型
	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;

	@Nullable
	Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;

    // 返回name名称Bean实例的别名
	String[] getAliases(String name);
}

1.3 BeanFactory继承体系

Spring源码之BeanFactory与FactoryBean

根据上面的UML图,可知日常经常使用的ApplicationContextClassPathXmlApplicationContext、以及AnnotationConfigApplicationContext的*接口都包含有BeanFactory;


2. FactoryBean

2.1 FactoryBean介绍

FactoryBean是一个工厂Bean,在日常代码中的Controller和ServiceImpl类基本都是被Spring通过反射去创建的Bean实例,而FactoryBean提供了另外一种创建Spring Bean实例的方式,就是实现它的getObject接口,然后返回的实例一样会被Spring IOC容器管理;

2.2 FactoryBean源码

public interface FactoryBean<T> {

	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

    // 返回FactoryBean生成的Bean实例
	@Nullable
	T getObject() throws Exception;

    // 返回FactoryBean生成的Bean实例的Class类型
	@Nullable
	Class<?> getObjectType();

    // 返回FactoryBean生成的Bean实例是否为单例
	default boolean isSingleton() {
		return true;
	}
}

2.3 FactoryBean实战

创建以下几个接口与类

动物接口:

public interface Animal {

	void sayHello();
}

猫类实现动物接口:

public class Cat implements Animal {

	@Override
	public void sayHello() {
		System.out.println("hello 喵喵喵");
	}
}

狗类实现动物接口:

public class Dog implements Animal {

	@Override
	public void sayHello() {
		System.out.println("hello 汪汪汪");
	}
}

创建一个AnimalFactoryBean实现FactoryBean接口:

public class AnimalFactoryBean implements FactoryBean<Animal> {

	private String type;

	@Override
	public Animal getObject() {
		switch (type) {
			case "cat":
				return new Cat();
			case "dog":
				return new Dog();
			default:
				return null;
		}
	}

	@Override
	public Class<?> getObjectType() {
		switch (type) {
			case "cat":
				return Cat.class;
			case "dog":
				return Dog.class;
			default:
				return null;
		}
	}

	public void setType(String type) {
		this.type = type;
	}
}

在applicationContext.xml配置文件中配置AnimalFactoryBean

<?xml version="1.0" encoding="UTF-8"?>
<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:p="http://www.springframework.org/schema/p"
	   xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

	<bean name="animalFactoryBean" class="cn.jackiegu.test.bean.AnimalFactoryBean" p:type="cat"/>
</beans>

创建一个测试类

public class AnimalBeanTest {

	public static void main(String[] args) {
		String path = "applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
		// FactoryBean工厂返回的实例
		Animal animal = (Animal) applicationContext.getBean("animalFactoryBean");
		animal.sayHello();
		// FactoryBean工厂实例
		AnimalFactoryBean animalFactoryBean = (AnimalFactoryBean) applicationContext.getBean("&animalFactoryBean");
		System.out.println(animalFactoryBean);
	}
}
// 运行结果
hello 喵喵喵
cn.jackiegu.test.bean.AnimalFactoryBean@77258e59
上一篇:FactoryBean工厂


下一篇:Spring 为什么会有 FactoryBean?