• Springboot重新加载Bean


    https://www.cnblogs.com/Chaos1973-newWorld/p/15031018.html

    参考:

    Java DefaultListableBeanFactory.destroyBean方法代码示例

    https://vimsky.com/examples/detail/java-method-org.springframework.beans.factory.support.DefaultListableBeanFactory.destroyBean.html

    Springboot重新加载Bean

    背景:

           有一个需求是要获取第三方的接口,加载到本地,通过本地调用接口获取结果,第三方接口会有版本变动,前端会有点击事件获取最新版本。

    设计:

          考虑到并不是每次都需要重新获取第三方接口,我将第三方接口以Configuration和bean的形式放入配置类中,示例代码如下:

    复制代码
    @Configuration
    public class DemoConfiguration {
        @Bean(name="execute")
        public static Execute getBean(){
            //TODO
    //Execute是我逻辑中需要的类
    Execute execute = ....(逻辑过程省略)
    return execute; } }
    复制代码

          后续的问题是,当第三方版本变动的时候,不能通过重启服务获取新的版本,而是重新加载配置类,获取新的实例,经过多方查找资料,汇总如下:

    复制代码
    mport org.springframework.context.ApplicationContext;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.support.DefaultListableBeanFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    public class DemoController {
        @Autowired
        private ApplicationContext applicationContext;
        @ResponseBody
        @PostMapping("/getVersion")
        public void reloadInstance(){
            //获取上下文
            DefaultListableBeanFactory defaultListableBeanFactory =
                    (DefaultListableBeanFactory)applicationContext.getAutowireCapableBeanFactory();
            //销毁指定实例 execute是上文注解过的实例名称 name="execute"
            defaultListableBeanFactory.destroySingleton("execute");
            //按照旧有的逻辑重新获取实例,Excute是我自己逻辑中的类
            Execute execute = DemoConfiguration.getBean();
            //重新注册同名实例,这样在其他地方注入的实例还是同一个名称,但是实例内容已经重新加载
            defaultListableBeanFactory.registerSingleton("execute",execute);
        }
    
    }
    复制代码

    经过验证可行。

    _________________________________________________________________________________________________________________

    Spring2.0 新特性之Bean新增范围session, request, global session

          在Spring2.0之前,我们对Bean的控制仅有两种:singleton和prototype。Spring默认的Bean是为singleton,在实际项目中,一般与状态无关的Bean,都可以使用singleton;

    而那些与具体状态相关的Bean,则应该显示的在Bean定义中设置为singleton=false。


      Spring2.0之前,我们是这么定义的:

          <bean id="singletonBean" class="myBean.singletonBean" />
          <bean id="notSingletonBean" class="myBean.notSingletonBean" singleton="false"/>


      在Spring2.0以后,因为增加了session, request, global session三种Bean的范围,所以在Bean的配置上,也发生了改变,不过Bean的默认范围仍然是singleton。
           

      新的写法如下:

    <bean id="newBean" class="myBean.newBean" scope="session | request | global session | singleton | prototype">
    <aop:scoped-proxy/>
    </bean>


           对于新增加的三种范围,Spring2.0对Bean的要求就是必须是在web环境中才能定义这三种范围。对比之前的singletoBean和notSingletonBean的XML定义,我们可以发现<aop:scoped-proxy/> 这个新的配置项。
          那么,这又是怎么一回事呢?
          为了理解为什么需要这一行和以前完全不同的Bean配置,我们需要对Spring2.0实现session, request, global session三种Bean的范围的原理进行研究。
          可以想象,对于开发人员来说,最重要的是得到一个实例,该实例提供给我们的就是和我们需要的Bean一样的接口。无论我们定义的Bean的范围如何,容器都要求可以将正确的实例返回给我们,那么,采用代理机制则可以完成这一个任务。代理机制屏蔽了基于Bean所定义的范围返回实例的要求,同时可以提供和我们所要求的Bean同样的接的口。基于这个原理,
    为了实现基于作用域机制的Bean的控制,Spring2.0引入了一个新的接口:

    public interface Scope {
     Object get(String name, ObjectFactory objectFactory);
     Object remove(String name);

       这个接口是用来表示Bean范围的接口,而在ConfigurableBeanFactory接口中定义了Bean工厂相关Scope注册的方法,使得可往Bean工厂中加入新范围的Bean。

    public interface ConfigurableBeanFactory extends HierarchicalBeanFactory,
     void registerScope(String scopeName, Scope scope);
     void destroyScopedBean(String beanName);
    }

       同时,Spring2.0在AbstractFactoryBean的getBean方法中实现了对Scope Bean支持以及在WebApplicationContext中注册session.request,global session三种Scope,这里就不继续贴代码了。

       最后需要提醒的是global session是应用于基于portlet的web应用中才有意义。

    ______________________________________________________________________________________________

      在容器ConfigurableBeanFactory接口中定义了Bean工厂有关Scope注册的相关方法,使得可往Bean工厂中加入新类型的Bean。
      public interface ConfigurableBeanFactory extends HierarchicalBeanFactory,
      void registerScope(String scopeName, Scope scope);//往Bean工厂中添加一个新的范围(默认只有两种范围:singleton及prototype)
      void destroyScopedBean(String beanName);//销毁B ean工厂中范围Bean
      }
    ————————————————————————————————————————————————————

  • 相关阅读:
    iOS5.1下emoji表情显示方框的解决办法
    iPhone处理图片(UIImage扩展类) 自动适应frame大小方法
    10个必需的iOS开发工具和资源
    转一篇:iOSOpenDev环境搭建以及使用
    自定义UITabbarController引发的血案
    (转) iphone开发资源汇总
    分类分享一下,关于push推送的经验吧
    关于IPHONE的设计模式
    IOS自动化打包介绍
    带有可变参数表的简化的printf函数
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/15897661.html
Copyright © 2020-2023  润新知