在Spring IOC容器的设计中,有两个主要的容器系列,一个是实现BeanFactory接口的简单容器系列,这系列容器只实现了容器的最基本功能;另一个是ApplicationContext应用上下文,它作为容器的高级形态而存在。应用上下文在简单容器的基础上,增加了许多面向框架的特性,同时对应用环境做了许多适配。
用户在使用容器时,可以使用转义符“&”来得到FactoryBean本身,用来区分通过容器来获得FactoryBean产生的对象和获取FactoryBean本身。例如,如果MyBean是一个FactoryBean,那么使用&MyBean得到的是FactoryBean,而不是MyBean这个FactoryBean产生出来的对象。
BeanFactory接口设计了getBean()方法,通过这个方法可以得到IOC容器中管理的bean,bean的去的是通过指定名字来索引的。
用户可以执行以下操作:
1.通过接口方法constainsBean让用户能够判断容器事都含有指定名字的Bean。
2.通过接口方法isSingleton来查询指定名字的Bean是否是Singleton类型的Bean。对于Singleton属性,用户可以在BeanDefinition中指定。
3.通过接口方法isPrototype来查询指定名字的Bean是否是prototype类型的。与Singleton属性是一样的,这个属性也可以由用户在BeanDefinition中指定。
4.通过接口方法isTypeMatch来查询指定了名字的Bean的Class类型是否是特定的Class类型。这个Class类型可以由用户来指定。
5.通过接口方法getType来查询指定名字的Bean的Class类型。
6.通过接口方法getAliases来查询指定了名字的Bean的所有别名,这些别名都是由用户在Beandefinition中定义的。
1 /* 2 * Copyright 2002-2013 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.springframework.beans.factory; 18 19 import org.springframework.beans.BeansException; 20 21 /** 22 * The root interface for accessing a Spring bean container. 23 * This is the basic client view of a bean container; 24 * further interfaces such as {@link ListableBeanFactory} and 25 * {@link org.springframework.beans.factory.config.ConfigurableBeanFactory} 26 * are available for specific purposes. 27 * 28 * <p>This interface is implemented by objects that hold a number of bean definitions, 29 * each uniquely identified by a String name. Depending on the bean definition, 30 * the factory will return either an independent instance of a contained object 31 * (the Prototype design pattern), or a single shared instance (a superior 32 * alternative to the Singleton design pattern, in which the instance is a 33 * singleton in the scope of the factory). Which type of instance will be returned 34 * depends on the bean factory configuration: the API is the same. Since Spring 35 * 2.0, further scopes are available depending on the concrete application 36 * context (e.g. "request" and "session" scopes in a web environment). 37 * 38 * <p>The point of this approach is that the BeanFactory is a central registry 39 * of application components, and centralizes configuration of application 40 * components (no more do individual objects need to read properties files, 41 * for example). See chapters 4 and 11 of "Expert One-on-One J2EE Design and 42 * Development" for a discussion of the benefits of this approach. 43 * 44 * <p>Note that it is generally better to rely on Dependency Injection 45 * ("push" configuration) to configure application objects through setters 46 * or constructors, rather than use any form of "pull" configuration like a 47 * BeanFactory lookup. Spring‘s Dependency Injection functionality is 48 * implemented using this BeanFactory interface and its subinterfaces. 49 * 50 * <p>Normally a BeanFactory will load bean definitions stored in a configuration 51 * source (such as an XML document), and use the {@code org.springframework.beans} 52 * package to configure the beans. However, an implementation could simply return 53 * Java objects it creates as necessary directly in Java code. There are no 54 * constraints on how the definitions could be stored: LDAP, RDBMS, XML, 55 * properties file, etc. Implementations are encouraged to support references 56 * amongst beans (Dependency Injection). 57 * 58 * <p>In contrast to the methods in {@link ListableBeanFactory}, all of the 59 * operations in this interface will also check parent factories if this is a 60 * {@link HierarchicalBeanFactory}. If a bean is not found in this factory instance, 61 * the immediate parent factory will be asked. Beans in this factory instance 62 * are supposed to override beans of the same name in any parent factory. 63 * 64 * <p>Bean factory implementations should support the standard bean lifecycle interfaces 65 * as far as possible. The full set of initialization methods and their standard order is:<br> 66 * 1. BeanNameAware‘s {@code setBeanName}<br> 67 * 2. BeanClassLoaderAware‘s {@code setBeanClassLoader}<br> 68 * 3. BeanFactoryAware‘s {@code setBeanFactory}<br> 69 * 4. ResourceLoaderAware‘s {@code setResourceLoader} 70 * (only applicable when running in an application context)<br> 71 * 5. ApplicationEventPublisherAware‘s {@code setApplicationEventPublisher} 72 * (only applicable when running in an application context)<br> 73 * 6. MessageSourceAware‘s {@code setMessageSource} 74 * (only applicable when running in an application context)<br> 75 * 7. ApplicationContextAware‘s {@code setApplicationContext} 76 * (only applicable when running in an application context)<br> 77 * 8. ServletContextAware‘s {@code setServletContext} 78 * (only applicable when running in a web application context)<br> 79 * 9. {@code postProcessBeforeInitialization} methods of BeanPostProcessors<br> 80 * 10. InitializingBean‘s {@code afterPropertiesSet}<br> 81 * 11. a custom init-method definition<br> 82 * 12. {@code postProcessAfterInitialization} methods of BeanPostProcessors 83 * 84 * <p>On shutdown of a bean factory, the following lifecycle methods apply:<br> 85 * 1. DisposableBean‘s {@code destroy}<br> 86 * 2. a custom destroy-method definition 87 * 88 * @author Rod Johnson 89 * @author Juergen Hoeller 90 * @author Chris Beams 91 * @since 13 April 2001 92 * @see BeanNameAware#setBeanName 93 * @see BeanClassLoaderAware#setBeanClassLoader 94 * @see BeanFactoryAware#setBeanFactory 95 * @see org.springframework.context.ResourceLoaderAware#setResourceLoader 96 * @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher 97 * @see org.springframework.context.MessageSourceAware#setMessageSource 98 * @see org.springframework.context.ApplicationContextAware#setApplicationContext 99 * @see org.springframework.web.context.ServletContextAware#setServletContext 100 * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization 101 * @see InitializingBean#afterPropertiesSet 102 * @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName 103 * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization 104 * @see DisposableBean#destroy 105 * @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName 106 */ 107 public interface BeanFactory { 108 109 /** 110 * Used to dereference a {@link FactoryBean} instance and distinguish it from 111 * beans <i>created</i> by the FactoryBean. For example, if the bean named 112 * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject} 113 * will return the factory, not the instance returned by the factory. 114 */ 115 String FACTORY_BEAN_PREFIX = "&"; 116 117 /** 118 * Return an instance, which may be shared or independent, of the specified bean. 119 * <p>This method allows a Spring BeanFactory to be used as a replacement for the 120 * Singleton or Prototype design pattern. Callers may retain references to 121 * returned objects in the case of Singleton beans. 122 * <p>Translates aliases back to the corresponding canonical bean name. 123 * Will ask the parent factory if the bean cannot be found in this factory instance. 124 * @param name the name of the bean to retrieve 125 * @return an instance of the bean 126 * @throws NoSuchBeanDefinitionException if there is no bean definition 127 * with the specified name 128 * @throws BeansException if the bean could not be obtained 129 */ 130 Object getBean(String name) throws BeansException; 131 132 /** 133 * Return an instance, which may be shared or independent, of the specified bean. 134 * <p>Behaves the same as {@link #getBean(String)}, but provides a measure of type 135 * safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the 136 * required type. This means that ClassCastException can‘t be thrown on casting 137 * the result correctly, as can happen with {@link #getBean(String)}. 138 * <p>Translates aliases back to the corresponding canonical bean name. 139 * Will ask the parent factory if the bean cannot be found in this factory instance. 140 * @param name the name of the bean to retrieve 141 * @param requiredType type the bean must match. Can be an interface or superclass 142 * of the actual class, or {@code null} for any match. For example, if the value 143 * is {@code Object.class}, this method will succeed whatever the class of the 144 * returned instance. 145 * @return an instance of the bean 146 * @throws NoSuchBeanDefinitionException if there is no such bean definition 147 * @throws BeanNotOfRequiredTypeException if the bean is not of the required type 148 * @throws BeansException if the bean could not be created 149 */ 150 <T> T getBean(String name, Class<T> requiredType) throws BeansException; 151 152 /** 153 * Return the bean instance that uniquely matches the given object type, if any. 154 * @param requiredType type the bean must match; can be an interface or superclass. 155 * {@code null} is disallowed. 156 * <p>This method goes into {@link ListableBeanFactory} by-type lookup territory 157 * but may also be translated into a conventional by-name lookup based on the name 158 * of the given type. For more extensive retrieval operations across sets of beans, 159 * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}. 160 * @return an instance of the single bean matching the required type 161 * @throws NoSuchBeanDefinitionException if no bean of the given type was found 162 * @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found 163 * @since 3.0 164 * @see ListableBeanFactory 165 */ 166 <T> T getBean(Class<T> requiredType) throws BeansException; 167 168 /** 169 * Return an instance, which may be shared or independent, of the specified bean. 170 * <p>Allows for specifying explicit constructor arguments / factory method arguments, 171 * overriding the specified default arguments (if any) in the bean definition. 172 * @param name the name of the bean to retrieve 173 * @param args arguments to use if creating a prototype using explicit arguments to a 174 * static factory method. It is invalid to use a non-null args value in any other case. 175 * @return an instance of the bean 176 * @throws NoSuchBeanDefinitionException if there is no such bean definition 177 * @throws BeanDefinitionStoreException if arguments have been given but 178 * the affected bean isn‘t a prototype 179 * @throws BeansException if the bean could not be created 180 * @since 2.5 181 */ 182 Object getBean(String name, Object... args) throws BeansException; 183 184 /** 185 * Does this bean factory contain a bean definition or externally registered singleton 186 * instance with the given name? 187 * <p>If the given name is an alias, it will be translated back to the corresponding 188 * canonical bean name. 189 * <p>If this factory is hierarchical, will ask any parent factory if the bean cannot 190 * be found in this factory instance. 191 * <p>If a bean definition or singleton instance matching the given name is found, 192 * this method will return {@code true} whether the named bean definition is concrete 193 * or abstract, lazy or eager, in scope or not. Therefore, note that a {@code true} 194 * return value from this method does not necessarily indicate that {@link #getBean} 195 * will be able to obtain an instance for the same name. 196 * @param name the name of the bean to query 197 * @return whether a bean with the given name is present 198 */ 199 boolean containsBean(String name); 200 201 /** 202 * Is this bean a shared singleton? That is, will {@link #getBean} always 203 * return the same instance? 204 * <p>Note: This method returning {@code false} does not clearly indicate 205 * independent instances. It indicates non-singleton instances, which may correspond 206 * to a scoped bean as well. Use the {@link #isPrototype} operation to explicitly 207 * check for independent instances. 208 * <p>Translates aliases back to the corresponding canonical bean name. 209 * Will ask the parent factory if the bean cannot be found in this factory instance. 210 * @param name the name of the bean to query 211 * @return whether this bean corresponds to a singleton instance 212 * @throws NoSuchBeanDefinitionException if there is no bean with the given name 213 * @see #getBean 214 * @see #isPrototype 215 */ 216 boolean isSingleton(String name) throws NoSuchBeanDefinitionException; 217 218 /** 219 * Is this bean a prototype? That is, will {@link #getBean} always return 220 * independent instances? 221 * <p>Note: This method returning {@code false} does not clearly indicate 222 * a singleton object. It indicates non-independent instances, which may correspond 223 * to a scoped bean as well. Use the {@link #isSingleton} operation to explicitly 224 * check for a shared singleton instance. 225 * <p>Translates aliases back to the corresponding canonical bean name. 226 * Will ask the parent factory if the bean cannot be found in this factory instance. 227 * @param name the name of the bean to query 228 * @return whether this bean will always deliver independent instances 229 * @throws NoSuchBeanDefinitionException if there is no bean with the given name 230 * @since 2.0.3 231 * @see #getBean 232 * @see #isSingleton 233 */ 234 boolean isPrototype(String name) throws NoSuchBeanDefinitionException; 235 236 /** 237 * Check whether the bean with the given name matches the specified type. 238 * More specifically, check whether a {@link #getBean} call for the given name 239 * would return an object that is assignable to the specified target type. 240 * <p>Translates aliases back to the corresponding canonical bean name. 241 * Will ask the parent factory if the bean cannot be found in this factory instance. 242 * @param name the name of the bean to query 243 * @param targetType the type to match against 244 * @return {@code true} if the bean type matches, 245 * {@code false} if it doesn‘t match or cannot be determined yet 246 * @throws NoSuchBeanDefinitionException if there is no bean with the given name 247 * @since 2.0.1 248 * @see #getBean 249 * @see #getType 250 */ 251 boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException; 252 253 /** 254 * Determine the type of the bean with the given name. More specifically, 255 * determine the type of object that {@link #getBean} would return for the given name. 256 * <p>For a {@link FactoryBean}, return the type of object that the FactoryBean creates, 257 * as exposed by {@link FactoryBean#getObjectType()}. 258 * <p>Translates aliases back to the corresponding canonical bean name. 259 * Will ask the parent factory if the bean cannot be found in this factory instance. 260 * @param name the name of the bean to query 261 * @return the type of the bean, or {@code null} if not determinable 262 * @throws NoSuchBeanDefinitionException if there is no bean with the given name 263 * @since 1.1.2 264 * @see #getBean 265 * @see #isTypeMatch 266 */ 267 Class<?> getType(String name) throws NoSuchBeanDefinitionException; 268 269 /** 270 * Return the aliases for the given bean name, if any. 271 * All of those aliases point to the same bean when used in a {@link #getBean} call. 272 * <p>If the given name is an alias, the corresponding original bean name 273 * and other aliases (if any) will be returned, with the original bean name 274 * being the first element in the array. 275 * <p>Will ask the parent factory if the bean cannot be found in this factory instance. 276 * @param name the bean name to check for aliases 277 * @return the aliases, or an empty array if none 278 * @see #getBean 279 */ 280 String[] getAliases(String name); 281 282 }