• Spring之BeanFactory和FactoryBean接口的区别


    BeanFactory和FactoryBean 2个很相似,但是区别很大。

    1、BeanFactory 

    BeanFactory接口是Spring容器的核心接口,负责:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

    ApplicationContext 这个应用上下文,我们经常用到,如

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

    而它就是继承了BeanFactory ,才会有可以getBean(String name) 这个功能。

    源代码如下:

     1 public interface BeanFactory {
     2     String FACTORY_BEAN_PREFIX = "&";
     3 
     4     Object getBean(String var1) throws BeansException;
     5 
     6     <T> T getBean(String var1, Class<T> var2) throws BeansException;
     7 
     8     <T> T getBean(Class<T> var1) throws BeansException;
     9 
    10     Object getBean(String var1, Object... var2) throws BeansException;
    11 
    12     <T> T getBean(Class<T> var1, Object... var2) throws BeansException;
    13 
    14     boolean containsBean(String var1);
    15 
    16     boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
    17 
    18     boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;
    19 
    20     boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;
    21 
    22     boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;
    23 
    24     Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
    25 
    26     String[] getAliases(String var1);
    27 }

    2、FactoryBean

    一般情况下,Spring通过反射机制利用<bean>的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,

    如果按照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。

    Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。

    说白了就是个普通的Bean,而这个bean可以自定义实现实例化,不想写xml配置,以及里面注入的内容很负责,写配置很困难等情况,跟注解版的@Bean 很相似,用的装饰设计模式,可新增功能。

    源代码如下:

    1 public interface FactoryBean<T> {
    2     T getObject() throws Exception;
    3 
    4     Class<?> getObjectType();
    5 
    6     boolean isSingleton();
    7 }

    很明显调用getObect方法就相当于applicationContext.getBean("student")

    具体使用如下:

    自定义创建了Mybean.class,实现FactoryBean接口

     1 public class MyBean implements FactoryBean<Student>
     2 {
     3     @Override
     4     public Student getObject() throws Exception
     5     {
     6         return new Student(){{
     7             setName("张三");
     8         }};
     9     }
    10 
    11     @Override
    12     public Class<?> getObjectType()
    13     {
    14         return Student.class;
    15     }
    16 
    17     @Override
    18     public boolean isSingleton()
    19     {
    20         return true;
    21     }
    22 }
    <bean id="myBean" class="qt.Dto.MyBean"></bean>
    1 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    2 Object myBean = applicationContext.getBean("myBean");
    3 System.out.println("isStudentBean:" + isStudentBean);
    4 System.out.println("myBean name:" + ((Student) myBean).getName());

    输出:

    isStudentBean:true
    myBean name:张三

    从上面的执行来看,明明注册className的是qt.Dto.MyBean, 最后获取的竟然是Student对象,不是本身的MyBean对象,

    很明显它调用的就是getObject方法,核心就是个代理方式

    如果我就想获取MyBean对象呢,还是有办法的,在对象 id前加 &就可以

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    Object myBean1 = applicationContext.getBean("&myBean");
    boolean isMyBean = myBean instanceof MyBean;
    System.out.println("isMyBean:" + isMyBean);
    System.out.println("myBean name:" + myBean1);

    输出:

    isStudentBean:true
    myBean name:张三

    用&来识别

  • 相关阅读:
    CodeIgniter(3.1.4)框架中成功/错误跳转
    CodeIgniter(3.1.4)框架-url重写,去除index.php
    CodeIgniter(3.1.4)框架中-使用多个公共控制器
    CodeIgniter(3.1.4)框架使用静态文件(js,css)
    PHP无限极分类
    PHP无限极分类
    spring中定时任务quartz2.2.3
    eclipse中git更新操作
    java中日期的换算处理
    使用spring-rabbit测试RabbitMQ消息确认(发送确认,接收确认)
  • 原文地址:https://www.cnblogs.com/zjtao/p/12193300.html
Copyright © 2020-2023  润新知