2013-02-12 70 views
0

我有一个spring应用程序,我正在使用Vaadin编写Web UI。为此,我正在使用Spring Vaadin Integration工具。Spring原型scoped bean,配置的设计模式

所以我扩展Vaadin类来定制它们并使用它们。例如,我有我的主要UI类,这是一个原型。 (应该实例每个用户打开浏览器窗口,一个新的。)

@Component 
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) 
public class MainUI extends UI { 

@Autowired 
private GameMapView gameMapView; 

@Override 
protected void init(VaadinRequest request) { 

     final VerticalLayout layout = new VerticalLayout(); 
     layout.setMargin(true); 
     setContent(layout); 

     gameMapView.configureGameMapView(); 
     layout.addComponent(gameMapView); 
    } 
} 

;进口我GameMapView,这也是一个原型组件,并延伸VerticalLayout的,然后我有一个GameMap原型组件,它扩展了GridLayout。

现在,当我使用GameMap类时,我需要使用维度以及中心图块位置对其进行配置。 (因此,它可以设置它有多大,什么瓷砖被观看。)它也需要用我的服务之一,从数据库中获取正确的瓷砖显示。

我想要做的是这些传递给构造函数,像这样:

@Component 
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) 
public class GameMap extends GridLayout { 

    @Autowired 
    private LandTileService lts; 

    public GameMap(int dimension, int xcoor, int ycoor) { 
     super(); 
     this.setWidth(80, Unit.PERCENTAGE); 
     this.setHeight(80, Unit.PERCENTAGE); 

//START configuration 

     this.setRows(dimension); 
     this.setColumns(dimension); 

     [use the land tile service and coordinates etc.] 
    //END configuration 
    } 
} 

但问题是,你不能使用自动装配的Spring bean一个Spring bean的构造函数中,而且你也不能使用带有自动布线弹簧bean的重载构造函数。

现在,我通过在我使用它之前调用一次我的Spring原型类的配置方法来解决这个问题,但它似乎是一个糟糕的解决方案。有没有更好的方法去解决这个问题?我希望能够强制x,y和z参数必须传递给Spring组件gamemap,然后才能开始使用它。

回答

2

但问题是,你不能使用自动装配的Spring bean一个Spring bean的构造函数中,你也不能与自动装配Autowired的Spring bean使用重载的构造函数。

默认情况下字段自动装配发生在bean构造之后,因此它在构造函数中不可用。

但是,您可以使用构造函数自动装配通过指定它在你的豆类配置文件:

<beans:beans xmlns="..." default-autowire="constructor"> 
</beans:beans> 

然后你就可以从构造

@Service 
public class FooService { 
} 

 

@Service 
public class CowService { 

    FooService fooService; 

    //FooService will be injected when CowService bean is constructed 
    public(FooService fooService) { 
    this.fooService = fooService; 
    } 
} 

注入你的bean现在,我越来越多了通过在我使用它之前调用一次我的Spring原型类的配置方法来解决这个问题,但它似乎是一个糟糕的解决方案。有没有更好的方法去解决这个问题?

在你的情况下,我会做的是创建一个工厂单身类“GameMapFactory”。把它作为一个bean,你可以在任何需要的地方注入。这个类将有一个方法“createGameMap(int dimension,int xcoord,int ycoord)”

+0

啊,是的。也许你是对的。我会看看为我的gameMaps制作一个工厂。这可能是最好的。你在构造器注入方面做得很好,但考虑到我有注入bean的注入其他bean的bean,对于我来说,在春季上下文初始化期间尝试使用bean可能是最好的选择。 – CorayThan 2013-02-12 06:50:36

0

有一个可以实现的接口(或者如果你喜欢的话可以是一个注解),它会触发一个方法在属性设置后被执行一次(如果有的话)。

您也可以将属性标记为@Required。 。 。关于构造函数注入,我不确定你到底面临着什么问题。 。 。 (自从我使用Spring之后已经有一段时间了)。

这里的API docs