1.BeanFactory
对于BeanFactory,它本质上是一个Factory,是一个容器,它是spring中最基本的容器,它的作用是配置,新建,管理各种bean以及它们之间的依赖关系。
看下源码
1 public interface BeanFactory { 2 3 /** 4 * Used to dereference a {@link FactoryBean} instance and distinguish it from 5 * beans <i>created</i> by the FactoryBean. For example, if the bean named 6 * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject} 7 * will return the factory, not the instance returned by the factory. 8 */ 9 String FACTORY_BEAN_PREFIX = "&"; 10 11 12 /** 13 * Return an instance, which may be shared or independent, of the specified bean. 14 * <p>This method allows a Spring BeanFactory to be used as a replacement for the 15 * Singleton or Prototype design pattern. Callers may retain references to 16 * returned objects in the case of Singleton beans. 17 * <p>Translates aliases back to the corresponding canonical bean name. 18 * Will ask the parent factory if the bean cannot be found in this factory instance. 19 * @param name the name of the bean to retrieve 20 * @return an instance of the bean 21 * @throws NoSuchBeanDefinitionException if there is no bean definition 22 * with the specified name 23 * @throws BeansException if the bean could not be obtained 24 */ 根据指定的beanName获取对应的bean对象 25 Object getBean(String name) throws BeansException; 26 27 /** 28 * Return an instance, which may be shared or independent, of the specified bean. 29 * <p>Behaves the same as {@link #getBean(String)}, but provides a measure of type 30 * safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the 31 * required type. This means that ClassCastException can't be thrown on casting 32 * the result correctly, as can happen with {@link #getBean(String)}. 33 * <p>Translates aliases back to the corresponding canonical bean name. 34 * Will ask the parent factory if the bean cannot be found in this factory instance. 35 * @param name the name of the bean to retrieve 36 * @param requiredType type the bean must match. Can be an interface or superclass 37 * of the actual class, or {@code null} for any match. For example, if the value 38 * is {@code Object.class}, this method will succeed whatever the class of the 39 * returned instance. 40 * @return an instance of the bean 41 * @throws NoSuchBeanDefinitionException if there is no such bean definition 42 * @throws BeanNotOfRequiredTypeException if the bean is not of the required type 43 * @throws BeansException if the bean could not be created 44 */根据名字和指定的类型获取bean对象 45 <T> T getBean(String name, Class<T> requiredType) throws BeansException; 46 47 /** 48 * Return an instance, which may be shared or independent, of the specified bean. 49 * <p>Allows for specifying explicit constructor arguments / factory method arguments, 50 * overriding the specified default arguments (if any) in the bean definition. 51 * @param name the name of the bean to retrieve 52 * @param args arguments to use when creating a bean instance using explicit arguments 53 * (only applied when creating a new instance as opposed to retrieving an existing one) 54 * @return an instance of the bean 55 * @throws NoSuchBeanDefinitionException if there is no such bean definition 56 * @throws BeanDefinitionStoreException if arguments have been given but 57 * the affected bean isn't a prototype 58 * @throws BeansException if the bean could not be created 59 * @since 2.5 60 */根据名字和创建对象时可能用到的参数来获取bean对象 61 Object getBean(String name, Object... args) throws BeansException; 62 63 /** 64 * Return the bean instance that uniquely matches the given object type, if any. 65 * <p>This method goes into {@link ListableBeanFactory} by-type lookup territory 66 * but may also be translated into a conventional by-name lookup based on the name 67 * of the given type. For more extensive retrieval operations across sets of beans, 68 * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}. 69 * @param requiredType type the bean must match; can be an interface or superclass. 70 * {@code null} is disallowed. 71 * @return an instance of the single bean matching the required type 72 * @throws NoSuchBeanDefinitionException if no bean of the given type was found 73 * @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found 74 * @throws BeansException if the bean could not be created 75 * @since 3.0 76 * @see ListableBeanFactory 77 */ 78 <T> T getBean(Class<T> requiredType) throws BeansException; 79 80 /** 81 * Return an instance, which may be shared or independent, of the specified bean. 82 * <p>Allows for specifying explicit constructor arguments / factory method arguments, 83 * overriding the specified default arguments (if any) in the bean definition. 84 * <p>This method goes into {@link ListableBeanFactory} by-type lookup territory 85 * but may also be translated into a conventional by-name lookup based on the name 86 * of the given type. For more extensive retrieval operations across sets of beans, 87 * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}. 88 * @param requiredType type the bean must match; can be an interface or superclass. 89 * {@code null} is disallowed. 90 * @param args arguments to use when creating a bean instance using explicit arguments 91 * (only applied when creating a new instance as opposed to retrieving an existing one) 92 * @return an instance of the bean 93 * @throws NoSuchBeanDefinitionException if there is no such bean definition 94 * @throws BeanDefinitionStoreException if arguments have been given but 95 * the affected bean isn't a prototype 96 * @throws BeansException if the bean could not be created 97 * @since 4.1 98 */ 99 <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; 100 101 102 /** 103 * Does this bean factory contain a bean definition or externally registered singleton 104 * instance with the given name? 105 * <p>If the given name is an alias, it will be translated back to the corresponding 106 * canonical bean name. 107 * <p>If this factory is hierarchical, will ask any parent factory if the bean cannot 108 * be found in this factory instance. 109 * <p>If a bean definition or singleton instance matching the given name is found, 110 * this method will return {@code true} whether the named bean definition is concrete 111 * or abstract, lazy or eager, in scope or not. Therefore, note that a {@code true} 112 * return value from this method does not necessarily indicate that {@link #getBean} 113 * will be able to obtain an instance for the same name. 114 * @param name the name of the bean to query 115 * @return whether a bean with the given name is present 116 */ 117 boolean containsBean(String name); 118 119 /** 120 * Is this bean a shared singleton? That is, will {@link #getBean} always 121 * return the same instance? 122 * <p>Note: This method returning {@code false} does not clearly indicate 123 * independent instances. It indicates non-singleton instances, which may correspond 124 * to a scoped bean as well. Use the {@link #isPrototype} operation to explicitly 125 * check for independent instances. 126 * <p>Translates aliases back to the corresponding canonical bean name. 127 * Will ask the parent factory if the bean cannot be found in this factory instance. 128 * @param name the name of the bean to query 129 * @return whether this bean corresponds to a singleton instance 130 * @throws NoSuchBeanDefinitionException if there is no bean with the given name 131 * @see #getBean 132 * @see #isPrototype 133 */ 134 boolean isSingleton(String name) throws NoSuchBeanDefinitionException; 135 136 /** 137 * Is this bean a prototype? That is, will {@link #getBean} always return 138 * independent instances? 139 * <p>Note: This method returning {@code false} does not clearly indicate 140 * a singleton object. It indicates non-independent instances, which may correspond 141 * to a scoped bean as well. Use the {@link #isSingleton} operation to explicitly 142 * check for a shared singleton instance. 143 * <p>Translates aliases back to the corresponding canonical bean name. 144 * Will ask the parent factory if the bean cannot be found in this factory instance. 145 * @param name the name of the bean to query 146 * @return whether this bean will always deliver independent instances 147 * @throws NoSuchBeanDefinitionException if there is no bean with the given name 148 * @since 2.0.3 149 * @see #getBean 150 * @see #isSingleton 151 */ 152 boolean isPrototype(String name) throws NoSuchBeanDefinitionException; 153 154 /** 155 * Check whether the bean with the given name matches the specified type. 156 * More specifically, check whether a {@link #getBean} call for the given name 157 * would return an object that is assignable to the specified target type. 158 * <p>Translates aliases back to the corresponding canonical bean name. 159 * Will ask the parent factory if the bean cannot be found in this factory instance. 160 * @param name the name of the bean to query 161 * @param typeToMatch the type to match against (as a {@code ResolvableType}) 162 * @return {@code true} if the bean type matches, 163 * {@code false} if it doesn't match or cannot be determined yet 164 * @throws NoSuchBeanDefinitionException if there is no bean with the given name 165 * @since 4.2 166 * @see #getBean 167 * @see #getType 168 */ 169 boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; 170 171 /** 172 * Check whether the bean with the given name matches the specified type. 173 * More specifically, check whether a {@link #getBean} call for the given name 174 * would return an object that is assignable to the specified target type. 175 * <p>Translates aliases back to the corresponding canonical bean name. 176 * Will ask the parent factory if the bean cannot be found in this factory instance. 177 * @param name the name of the bean to query 178 * @param typeToMatch the type to match against (as a {@code Class}) 179 * @return {@code true} if the bean type matches, 180 * {@code false} if it doesn't match or cannot be determined yet 181 * @throws NoSuchBeanDefinitionException if there is no bean with the given name 182 * @since 2.0.1 183 * @see #getBean 184 * @see #getType 185 */ 186 boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException; 187 188 /** 189 * Determine the type of the bean with the given name. More specifically, 190 * determine the type of object that {@link #getBean} would return for the given name. 191 * <p>For a {@link FactoryBean}, return the type of object that the FactoryBean creates, 192 * as exposed by {@link FactoryBean#getObjectType()}. 193 * <p>Translates aliases back to the corresponding canonical bean name. 194 * Will ask the parent factory if the bean cannot be found in this factory instance. 195 * @param name the name of the bean to query 196 * @return the type of the bean, or {@code null} if not determinable 197 * @throws NoSuchBeanDefinitionException if there is no bean with the given name 198 * @since 1.1.2 199 * @see #getBean 200 * @see #isTypeMatch 201 */ 202 Class<?> getType(String name) throws NoSuchBeanDefinitionException; 203 204 /** 205 * Return the aliases for the given bean name, if any. 206 * All of those aliases point to the same bean when used in a {@link #getBean} call. 207 * <p>If the given name is an alias, the corresponding original bean name 208 * and other aliases (if any) will be returned, with the original bean name 209 * being the first element in the array. 210 * <p>Will ask the parent factory if the bean cannot be found in this factory instance. 211 * @param name the bean name to check for aliases 212 * @return the aliases, or an empty array if none 213 * @see #getBean 214 */ 215 String[] getAliases(String name); 216 217 }
2.FactoryBean
factoryBean,它本质上是一个bean,工厂bean,可以用来生成其它bean对象。如果需要获取该工厂bean对象它自己,则需要在该beanName前面加上 & 符号。
2.1 用法
新建一个工厂bean,该bean实现了FactoryBean接口
package com.demo.spring.entity; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; /** * @author chenyk * @date 2018年6月22日 */ @Component("carFactoryBean") public class CarFactoryBean implements FactoryBean<Car>,InitializingBean{ private Car car; public void afterPropertiesSet() throws Exception { this.car = new Car(); } //此处就是返回的对象 public Car getObject() throws Exception { return this.car; } public Class<?> getObjectType() { return Car.class; } public boolean isSingleton() { return true; } }
创建一个car类
public class Car { public void run(){ System.out.println("run fast..."); } }
运行发现:
public void testApplicationContext(){ //在启动容器时,解析注册beanDefinition,实例化bean,然后完成依赖注入,最后初始化bean @SuppressWarnings("resource") ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-context.xml"); System.out.println(applicationContext.getBean("carFactoryBean").getClass()); //获取的是Car System.out.println( applicationContext.getBean("&carFactoryBean").getClass()); //获取的是CarFactoryBean }
输出:
class com.demo.spring.entity.Car
2018-06-25 09:08:41,469 DEBUG [AbstractBeanFactory.java:251] : Returning cached instance of singleton bean 'carFactoryBean'
class com.demo.spring.entity.CarFactoryBean
2.2 源码分析
public interface FactoryBean<T> { /** * Return an instance (possibly shared or independent) of the object * managed by this factory. * <p>As with a {@link BeanFactory}, this allows support for both the * Singleton and Prototype design pattern. * <p>If this FactoryBean is not fully initialized yet at the time of * the call (for example because it is involved in a circular reference), * throw a corresponding {@link FactoryBeanNotInitializedException}. * <p>As of Spring 2.0, FactoryBeans are allowed to return {@code null} * objects. The factory will consider this as normal value to be used; it * will not throw a FactoryBeanNotInitializedException in this case anymore. * FactoryBean implementations are encouraged to throw * FactoryBeanNotInitializedException themselves now, as appropriate. * @return an instance of the bean (can be {@code null}) * @throws Exception in case of creation errors * @see FactoryBeanNotInitializedException */ //获取bean对象
T getObject() throws Exception; /** * Return the type of object that this FactoryBean creates, * or {@code null} if not known in advance. * <p>This allows one to check for specific types of beans without * instantiating objects, for example on autowiring. * <p>In the case of implementations that are creating a singleton object, * this method should try to avoid singleton creation as far as possible; * it should rather estimate the type in advance. * For prototypes, returning a meaningful type here is advisable too. * <p>This method can be called <i>before</i> this FactoryBean has * been fully initialized. It must not rely on state created during * initialization; of course, it can still use such state if available. * <p><b>NOTE:</b> Autowiring will simply ignore FactoryBeans that return * {@code null} here. Therefore it is highly recommended to implement * this method properly, using the current state of the FactoryBean. * @return the type of object that this FactoryBean creates, * or {@code null} if not known at the time of the call * @see ListableBeanFactory#getBeansOfType */ //获取bean类型
Class<?> getObjectType(); /** * Is the object managed by this factory a singleton? That is, * will {@link #getObject()} always return the same object * (a reference that can be cached)? * <p><b>NOTE:</b> If a FactoryBean indicates to hold a singleton object, * the object returned from {@code getObject()} might get cached * by the owning BeanFactory. Hence, do not return {@code true} * unless the FactoryBean always exposes the same reference. * <p>The singleton status of the FactoryBean itself will generally * be provided by the owning BeanFactory; usually, it has to be * defined as singleton there. * <p><b>NOTE:</b> This method returning {@code false} does not * necessarily indicate that returned objects are independent instances. * An implementation of the extended {@link SmartFactoryBean} interface * may explicitly indicate independent instances through its * {@link SmartFactoryBean#isPrototype()} method. Plain {@link FactoryBean} * implementations which do not implement this extended interface are * simply assumed to always return independent instances if the * {@code isSingleton()} implementation returns {@code false}. * @return whether the exposed object is a singleton * @see #getObject() * @see SmartFactoryBean#isPrototype() */
//是否是单例模式
boolean isSingleton(); }