做者:gcdd1993 来源:http://www.javashuo.com/article/p-ahaojrud-bv.htmlhtml
BeanFactory
:Spring Bean容器的根接口FactoryBean
:各个对象的工厂接口,若是bean实现了这个接口,它将被用做对象的工厂,而不是直接做为bean实例。public interface BeanFactory { //标注是获取FactoryBean的实现类,而不是调用getObject()获取的实例 String FACTORY_BEAN_PREFIX = "&"; 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; 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; Class<?> getType(String name) throws NoSuchBeanDefinitionException; String[] getAliases(String name); }
从源码的方法定义上,就能够看出,BeanFactory
做为bean的容器管理器,提供了一系列获取bean以及获取bean属性的方法。java
写一个小例子试验下: SimpleBean:spring
public class SimpleBean { public void send() { System.out.println("Hello Spring Bean!"); } }
Spring配置文件config.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" xmlns:context="http://www.springframework.org/schema/context" 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 id="simpleBean" class="base.SimpleBeanFactoryBean"/> </beans>
测试方法:yii
public static void main(String[] args) throws Exception { ApplicationContext context = new ClassPathXmlApplicationContext("config.xml"); BeanFactory beanFactory = context.getAutowireCapableBeanFactory(); System.out.println("经过名称获取bean"); SimpleBean simpleBean = (SimpleBean) beanFactory.getBean("simpleBean"); simpleBean.send(); System.out.println("经过名称和类型获取bean"); simpleBean = beanFactory.getBean("simpleBean", SimpleBean.class); simpleBean.send(); System.out.println("经过类型获取bean"); simpleBean = beanFactory.getBean(SimpleBean.class); simpleBean.send(); boolean containsBean = beanFactory.containsBean("simpleBean"); System.out.println("是否包含 simpleBean ? " + containsBean); boolean singleton = beanFactory.isSingleton("simpleBean"); System.out.println("是不是单例? " + singleton); boolean match = beanFactory.isTypeMatch("simpleBean", ResolvableType.forClass(SimpleBean.class)); System.out.println("是不是SimpleBean类型 ? " + match); match = beanFactory.isTypeMatch("simpleBean", SimpleBean.class); System.out.println("是不是SimpleBean类型 ? " + match); Class<?> aClass = beanFactory.getType("simpleBean"); System.out.println("simpleBean 的类型是 " + aClass.getName()); String[] aliases = beanFactory.getAliases("simpleBean"); System.out.println("simpleBean 的别名 : " + Arrays.toString(aliases)); }
控制台结果:ide
经过名称获取bean Hello Spring Bean! 经过名称和类型获取bean Hello Spring Bean! 经过类型获取bean Hello Spring Bean! 是否包含 simpleBean ? true 是不是单例? true 是不是SimpleBean类型 ? true 是不是SimpleBean类型 ? true simpleBean 的类型是 base.SimpleBean simpleBean 的别名 : []
public interface FactoryBean<T> { /** * 获取一个bean,若是配置了工厂bean,在getBean的时候,将会调用此方法,获取一个bean */ T getObject() throws Exception; /** * 获取bean的类型 */ Class<?> getObjectType(); /** * 是不是单例 */ boolean isSingleton(); }
接口是泛型,定义了三个方法,其中getObject()
是工厂模式的体现,将会经过此方法返回一个bean的实例。学习
一个小例子:测试
public class SimpleBeanFactoryBean implements FactoryBean<SimpleBean> { @Override public SimpleBean getObject() throws Exception { System.out.println("MyFactoryBean getObject"); return new SimpleBean(); } @Override public Class<?> getObjectType() { System.out.println("MyFactoryBean getObjectType"); return SimpleBean.class; } @Override public boolean isSingleton() { return false; } }
以上能够修改成单例模式,能够作成线程安全的单例,可塑性较高。网站
配置文件config.xml:ui
<?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" 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 id="simple" class="base.SimpleBeanFactoryBean"/> </beans>
注意,咱们在这里只配置了SimpleBeanFactoryBean
,并无配置SimpleBean
,接下来看下getBean
方法的输出。
ApplicationContext context = new ClassPathXmlApplicationContext("config.xml"); SimpleBean simpleBean = context.getBean(SimpleBean.class); simpleBean.send();
控制台输出:
MyFactoryBean getObjectType MyFactoryBean getObject Hello Spring Bean!
由此咱们能够看出FactoryBean的执行流程
getObjectType
获取bean的类型getObject
方法获取bean的实例BeanFactory
和FactoryBean
其实没有关系,只是名称比较像而已。
BeanFactory
是IOC最基本的容器,负责生产和管理bean,它为其余具体的IOC容器提供了最基本的规范。FactoryBean
是一个接口,当在IOC容器中的Bean实现了FactoryBean
后,经过getBean(String BeanName)
获取到的Bean对象并非FactoryBean
的实现类对象,而是这个实现类中的getObject()
方法返回的对象。要想获取FactoryBean
的实现类,就要getBean(&BeanName)
,在BeanName
以前加上&。欢迎关注个人公众号::一点教程。得到独家整理的学习资源和平常干货推送。 若是您对个人系列教程感兴趣,也能够关注个人网站:yiidian.com