Spring源码之BeanFactory与FactoryBean

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继承体系

在这里插入图片描述

根据上面的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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JackieGGu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值