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

    BeanFactory 和 FactoryBean的区别?

    • BeanFactory是个bean工厂,也就是IOC容器或对象工厂,在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的,提供了实例化对象和获取对象的功能。是IOC最基本的容器,负责生产和管理bean,它为其他具体的IOC容器实现提供了最基本的规范,例如DefaultListableBeanFactory, XmlBeanFactory, ApplicationContext 等具体的容器都是实现了BeanFactory,再在其基础之上附加了其他的功能。           

    public interface BeanFactory {    
        String FACTORY_BEAN_PREFIX = "&";    
        Object getBean(String name) throws BeansException;    
        <T> T getBean(String name, Class<T> requiredType) throws BeansException;    
        <T> T getBean(Class<T> requiredType) throws BeansException;    
        Object getBean(String name, Object... args) throws BeansException;    
        boolean containsBean(String name);    
        boolean isSingleton(String name) throws NoSuchBeanDefinitionException;    
        boolean isPrototype(String name) throws NoSuchBeanDefinitionException;    
        boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;    
        Class<?> getType(String name) throws NoSuchBeanDefinitionException;    
        String[] getAliases(String name);    
    } 
    BeanFactory

              使用场景:

      • 从Ioc容器中获取Bean(byName or byType)

      • 检索Ioc容器中是否包含指定的Bean

      • 判断Bean是否为单例

    • FactoryBean是个Bean,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。

      使用场景

      • ProxyFactoryBean

    BeanFactory和FactoryBean区别

    他们两个都是 创建bean对象的

    BeanFactory:提供了类似模板的方法,根据模板方法实现具体的bean创建

    BeanFactory

    FactoryBean:则是提供了定制化的 ,独特的,与众不同的Bean创建,你可以根据自己的方式创建bean,最后通过FactoryBean中的getObject获取你定制化实现的bean

    FactoryBean里面有三个方法:目的是为了做扩展,Spring Cloud 用到了FactoryBean如(FeignClientFactoryBean),feign实现了FactoryBean,getObject可以获取

    当在IOC容器中的Bean实现了FactoryBean接口后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。

    MapperFactoryBean通过实现FactoryBean中的getObject()方法生成Mapper对应的代理对象

    SqlSessionFactoryBean:创建DefaultSqlSession

    FactoryBean接口
       public Object getObject() {
            return this.getTarget();
        }
    <T> T getTarget() {
            FeignContext context = (FeignContext)this.applicationContext.getBean(FeignContext.class);
            Builder builder = this.feign(context);
            if (!StringUtils.hasText(this.url)) {
                if (!this.name.startsWith("http")) {
                    this.url = "http://" + this.name;
                } else {
                    this.url = this.name;
                }
    
                this.url = this.url + this.cleanPath();
                return this.loadBalance(builder, context, new HardCodedTarget(this.type, this.name, this.url));
            } else {
                if (StringUtils.hasText(this.url) && !this.url.startsWith("http")) {
                    this.url = "http://" + this.url;
                }
    
                String url = this.url + this.cleanPath();
                Client client = (Client)this.getOptional(context, Client.class);
                if (client != null) {
                    if (client instanceof FeignBlockingLoadBalancerClient) {
                        client = ((FeignBlockingLoadBalancerClient)client).getDelegate();
                    }
    
                    builder.client(client);
                }
    
                Targeter targeter = (Targeter)this.get(context, Targeter.class);
                return targeter.target(this, builder, context, new HardCodedTarget(this.type, this.name, url));
            }
        }
    FeignClientFactoryBean
      public T getObject() throws Exception {
            return this.getSqlSession().getMapper(this.mapperInterface);
        }
    
    //通过代理创建对象
      public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
            MybatisMapperProxyFactory<T> mapperProxyFactory = (MybatisMapperProxyFactory)this.knownMappers.get(type);
            if (mapperProxyFactory == null) {
                throw new BindingException("Type " + type + " is not known to the MybatisPlusMapperRegistry.");
            } else {
                try {
                    return mapperProxyFactory.newInstance(sqlSession);
                } catch (Exception var5) {
                    throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
                }
            }
        }
    MapperFactoryBean

     

     

     

     

     

     

     

    BeanFactory和ApplicationContext的异同

      

    BeanFactory:

    BeanFactory在启动的时候不会去实例化Bean,中有从容器中拿Bean的时候才会去实例化;

    ApplicationContext:

    ApplicationContext在启动的时候就把所有的Bean全部实例化了。它还可以为Bean配置lazy-init=true来让Bean延迟实例化;  

    应用上下文,继承BeanFactory接口,它是Spring的一各更高级的容器,提供了更多的有用的功能;

    1) 国际化(MessageSource)

    2) 访问资源,如URL和文件(ResourceLoader)

    3) 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层  

    4) 消息发送、响应机制(ApplicationEventPublisher)

    5) AOP(拦截器)

    ApplicationContext:继承了bean工厂,环境,事件发布功能资源解析,获取资源等功能,功能比beanFactory更全

    主要实现类: 

    1. AnnotationConfigApplicationContext
    2. ClassPathXmlApplicationContext
    3. FileSystemXmlApplicationContext 

    相同:

    • Spring提供了两种不同的IOC 容器,一个是BeanFactory,另外一个是ApplicationContext,它们都是Java interface,ApplicationContext继承于BeanFactory(ApplicationContext继承ListableBeanFactory)。

    • 它们都可以用来配置XML属性,也支持属性的自动注入。

    • 而ListableBeanFactory继承BeanFactory),BeanFactory 和 ApplicationContext 都提供了一种方式,使用getBean("bean name")获取bean。

    不同:

    • 当你调用getBean()方法时,BeanFactory仅实例化bean,而ApplicationContext 在启动容器的时候实例化单例bean,不会等待调用getBean()方法时再实例化。

    • BeanFactory不支持国际化,即i18n,但ApplicationContext提供了对它的支持。

    • BeanFactory与ApplicationContext之间的另一个区别是能够将事件发布到注册为监听器的bean。

    • BeanFactory 的一个核心实现是XMLBeanFactory 而ApplicationContext 的一个核心实现是ClassPathXmlApplicationContext,Web容器的环境我们使用WebApplicationContext并且增加了getServletContext 方法。

    • 如果使用自动注入并使用BeanFactory,则需要使用API注册AutoWiredBeanPostProcessor,如果使用ApplicationContext,则可以使用XML进行配置。

    简而言之,BeanFactory提供基本的IOC和DI功能,而ApplicationContext提供高级功能,BeanFactory可用于测试和非生产使用,但ApplicationContext是功能更丰富的容器实现,应该优于BeanFactory

  • 相关阅读:
    可持久化线段树区间查询 + 永久化标记 T^T online judge 2507
    可持久化线段树
    T^T online judge 3441
    食物链
    T^T ONLINE JUDGE 2592
    HDU 6312 GAME
    HDU 1430 魔板
    栈的操作链表+数组版
    Codeforces Round #468 (Div. 2, based on Technocup 2018 Final Round) D. Peculiar apple-tree
    Codeforces Round #468 (Div. 2, based on Technocup 2018 Final Round) C. Laboratory Work
  • 原文地址:https://www.cnblogs.com/fanBlog/p/12851433.html
Copyright © 2011-2022 走看看