zoukankan      html  css  js  c++  java
  • BeanFactory和FactoryBean

    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(); }
  • 相关阅读:
    Appium的三种启动方式(转载)
    select单选框和多选框设置默认值
    JavaScript获取到ModelAndView的对象
    Selenium+PageObject+Java实现测试用例
    2017ACM-ICPC 青岛 K.Our Journey of Xian Ends
    Django简单数据库交互演示
    简单树刨+线段树模板 877E
    ACM 二维离散化模板 hdu5925
    code::blocks配置头文件#include<bits/stdc++.h>
    百度之星初赛b
  • 原文地址:https://www.cnblogs.com/51life/p/9214079.html
Copyright © 2011-2022 走看看