【问题标题】:Spring Prototype scoped bean, design pattern for configurationSpring Prototype 作用域 bean,用于配置的设计模式
【发布时间】:2013-02-12 00:29:02
【问题描述】:

我有一个 Spring 应用程序,我正在使用 Vaadin 编写 Web UI。为此,我使用了Spring Vaadin Integration 工具。

所以我正在扩展 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,你也不能在自动装配的 spring bean 中使用重载的构造函数。

现在,我通过创建一个配置方法来解决这个问题,我只在我的 spring 原型类上调用一次,然后再使用它们,但这似乎是一个糟糕的解决方案。有没有更好的方法来解决这个问题?我希望能够强制 x、y 和 z 参数必须先传递给 Spring Component 游戏地图,然后才能开始使用它。

【问题讨论】:

    标签: java spring vaadin


    【解决方案1】:

    但问题是你不能在 spring bean 的构造函数中使用自动装配的 spring bean,你也不能在 autowired spring bean 中使用重载的构造函数。 p>

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

    但是,您可以通过在 bean 配置文件中指定构造函数自动装配来使用它:

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

    然后你可以从构造函数中注入你的bean

    @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;
       }
    }
    

    现在,我通过在我的 spring 原型类上调用一次配置方法来解决这个问题,然后再使用它们,但这似乎是一个糟糕的解决方案。有没有更好的方法来解决这个问题?

    在您的情况下,我要做的是创建一个工厂单例类“GameMapFactory”。将其作为 bean 放置,您可以将其注入任何您需要的地方。该类将有一个方法“createGameMap(int dimension, int xcoord, int ycoord)”

    【讨论】:

    • 啊,是的。你可能是对的。我会考虑为我的游戏地图制作工厂。那可能是最好的。您对构造函数注入提出了一个很好的观点,但是考虑到我有注入其他 bean 的 bean 注入 bean,最好不要在它们的 spring 上下文初始化期间尝试使用 bean。
    【解决方案2】:

    您可以实现一个接口(如果您愿意,也可以实现一个注释),它会在设置属性后触发一个方法(如果有)执行一次。

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

    这是API docs

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 2021-04-26
      • 2013-12-25
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      • 2017-06-27
      相关资源
      最近更新 更多