spring vaadin_Spring和Vaadin的鸡肉和鸡蛋问题

spring vaadin

我越深入Vaadin ,就越喜欢它:与肮脏的管道隔离,丰富的组件,与portlet的集成,Vaadin拥有了一切。

无论如何,您对技术的探索越多,跌倒众所周知的兔子洞的机会就越大。 我是昨天才找到的,并提出了解决方案。 问题如下:在Vaadin中,应用程序对象绑定到会话。 由于我是Spring的忠实拥护者,因此使用Spring连接我的所有依赖关系确实很有意义。 这样,我将所有与应用程序相关的bean(应用程序,窗口,按钮,资源等)的作用域限定为如下会话:

<?xml version="1.0" encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
  <context:annotation-config/>
  <beanid="application"scope="session">
  <aop:scoped-proxy/>
...
</beans>

效果很好,直到您碰巧使用DI进行进一步布线为止。 进一步说,我的意思是将窗口连接到应用程序,将按钮连接到窗口,然后将资源(图标)连接到按钮。 这是导致循环依赖的最后一步。 图标资源在com.vaadin.terminal.ClassResource中由com.vaadin.terminal.ClassResource 。 该类有两个构造函数,都需要一个应用程序实例。

因此,依赖关系周期为:应用程序→窗口→按钮→资源→应用程序。 Spring不喜欢它,并抛出一个标记为的异常来对此进行强烈抗议,因此Requested bean is currently in creation: Is there an unresolvable circular reference?

我认为在这种情况下, ClassResource的设计不适合。 这就是为什么我设计了一个与Spring延迟实例化对齐的类:由于应用程序是基于会话的,因此Spring使用了一个代理,该代理将实例化从应用程序启动(Spring正常行为)推迟到会话使用。 关键是实现ApplicationResource接口,该接口需要一个接口,但仅在需要时设置应用程序:

publicclassDeferredClassResourceimplementsApplicationResource{

  privatestaticfinallongserialVersionUID=1L;

  privateintbufferSize=0;
  privatelongcacheTime=DEFAULT_CACHETIME;
  privateClass<?>associatedClass;
  privatefinalStringresourceName;
  privateApplicationapplication;

  publicDeferredClassResource(StringresourceName){
    if(resourceName==null){
      thrownewIllegalArgumentException("Resource name cannot be null");
    }
    this.resourceName=resourceName;
  }

  publicDeferredClassResource(Class<?>associatedClass,StringresourceName){
    this(resourceName);
    if(associatedClass==null){
      thrownewIllegalArgumentException("Associated class cannot be null");
    }
    this.associatedClass=associatedClass;
  }

...// standard getters

  @Override
  publicStringgetFilename(){
    intindex=0;
    intnext=0;
    while((next=resourceName.indexOf('/',index))>0
      &&next+1<resourceName.length()){
      index=next+1;
    }
    returnresourceName.substring(index);
  }

  @Override
  publicDownloadStreamgetStream(){
    finalDownloadStreamds=newDownloadStream(associatedClass
      .getResourceAsStream(resourceName),getMIMEType(),
      getFilename());
    ds.setBufferSize(getBufferSize());
    ds.setCacheTime(cacheTime);
    returnds;
  }

  @Override
  publicStringgetMIMEType(){
    returnFileTypeResolver.getMIMEType(resourceName);
  }

  publicvoidsetApplication(Applicationapplication){
    if(this.application==application){
      return;
    }
    if(this.application!=null){
      thrownewIllegalStateException("Application is already set for this resource");
    }
    this.application=application;
    associatedClass=application.getClass();
    application.addResource(this);
  }
}

DeferredClassResource只是ClassResource一个副本,但具有一些适应性,这些适应性使以后可以设置应用程序,而不仅仅是在构造函数中。 我的问题解决了,我只需要让应用程序知道我的资源,即可在@PostConstruct注释方法中调用setApplication(this)

翻译自: https://blog.frankel.ch/chicken-and-egg-problem-with-spring-and-vaadin/

spring vaadin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值