簡體   English   中英

Spring MVC,Scoped Controller使用基於類的代理:'已經有scopedTarget bean方法'。

[英]Spring MVC, Scoped Controller using Class-Based Proxy: 'There is already scopedTarget bean method.'

我正在使用Spring MVC創建一個可視化編輯器Web應用程序。

visualizaton有一些屬性:

public class VisualizationProperties {
    double strokeWidth = 1;
    Rectangle selectedArea;
}

每個瀏覽器會話應該有一個,所以我將其定義為會話范圍的bean:

@Component
@Scope("session")
public class VisualizationProperties {
    ...

因為我想從服務中訪問它...

@Service
public class VisualizationService {

    @Resource
    private VisualizationProperties properties;

    public void createVisualization () {
        //create visualization using properties
        ...
    }
}

...我通過代理定義訪問:

@Component
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class VisualizationProperties {
    ...

使成員私有,並添加getters + setter。

到目前為止完美。

現在我希望客戶端能夠讀取和更新屬性。

所以我將bean更改為控制器並添加訪問自身的方法:

@Controller
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class VisualizationProperties {

    private double strokeWidth = 1;
    private Rectangle selectedArea;

    ... //getters + setters

    @RequestMapping(value="/properties", method=RequestMethod.GET)
    public @ResponseBody VisualizationProperties getProperties () {
        return this;
    }

    @RequestMapping(value="/properties", method=RequestMethod.POST)
    public @ResponseBody void setProperties (@RequestBody VisualizationProperties newProperties) {
        this.strokeWidth  = newProperties.strokeWidth;
        this.selectedArea = newProperties.selectedArea;
    }

}

在啟動時導致以下異常:

IllegalStateException: Ambiguous mapping found.

Cannot map 'visualizationProperties' bean method getProperties() to {[/properties],methods=[GET],...}:

There is already 'scopedTarget.visualizationProperties' bean method.

這是為什么?

這里的問題是雙重的。 首先,您要注釋一個已經使用@Controller注釋的類。

@Controller
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class VisualizationProperties {

其次,您正在使用范圍代理。 在這種情況下,Spring將注冊兩個bean定義。 一個名為visualizationProperties用於實際bean,另一個名為scopedTarget.visualizationProperties ,用作創建代理的FactoryBean

處理程序方法注冊過程(對於@Controller bean和@RequestMapping方法)通過查找上下文中的所有bean 名稱 ,查找其類型,掃描該類型的方法以及注冊這些方法(如果使用@RequestMapping注釋)來工作。

由於Spring解決了這兩個visualizationPropertiesscopedTarget.visualizationProperties bean名字類型的豆VisualizationProperties@RequestMapping注解的方法,它會嘗試注冊這兩個,沒有按規定因為映射沖突的第二個(你不能有兩個處理程序映射到相同請求)。

我建議的解決方案是重構並創建一個委托給會話范圍的VisualizationProperties bean的專用@Controller類(不代理)。

有效的替代方案:

  • 將訪問方法移動到不同的控制器.. 封裝meh!
  • 使用proxyMode=ScopedProxyMode.INTERFACES ,將可愛的小屬性POJO移動到VisualizationProperties Impl並為它引入一個接口.. proxyMode=ScopedProxyMode.INTERFACES

其他想法?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM