从组件bean获取原型bean的正确设计模式是什么?

时间:2015-07-12 13:34:24

标签: java spring javabeans lifetime

我只是想知道一个好的架构设计是什么样的。

  • 假设我们有一个CarRepository来管理汽车租赁应用程序中Car类型的所有bean。
  • Car bean属于原型
  • CarRepository bean属于类型存储库(单例)
  • 现在,要求CarRepository创建一个新的Car bean,例如当租赁公司买了一辆新车时。

当然,我可以实现ApplicatioContextAware并使用context.getBean("car"),但对我来说,它不适合依赖注入的想法。将寿命较短的豆子注入单身人员的最佳做法是什么?

更新:也许我应该添加一个示例以使其更清晰。

@Repository
public class CarRepository {
private List<Car> cars;

    public void registerNewCar(int id, String model) {
        // I don't want to access the Spring context via ApplicationContextAware here

        // Car tmp = (Car) context.getBean("car");
        // car.setId(id);
        // car.setModel(model);
        // cars.add(tmp);
    }
}

@Scope("prototype")
public class Car {
    private int id;
    private String model;

    // getter and setters
}

2 个答案:

答案 0 :(得分:1)

Spring提供了一种机制,可以处理在较长寿命的bean中注入寿命较短的bean。它被称为范围代理。它是如何工作的,单例注入了一个代理,它将通过搜索bean实例的较短范围(如会话或请求)并委托给该实例来处理方法调用。

如果您使用xml或注释来配置应用程序或使用的是哪个版本的Spring,那么您没有指定。您可以在reference guide中阅读有关使用xml配置范围代理的更多信息。我将举例说明如何在Spring 4-ish环境中使用注释对其进行配置。

对我来说,最好的方法是使用元注释机制。它允许您创建自己的注释,以后Spring将使用它来配置您的应用程序。例如:

@Retention(RUNTIME)
@Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.TARGET_CLASS)
public @interface SessionScoped{
}

这样的注释,在@Component(或@Service或任何其他特化)类或Java配置中的@Bean方法上指定时,将导致该bean作为代理注入。例如:

@Configuration
@EnableAspectJAutoProxy
public class MyConfig{

    @SessionScoped
    @Bean
    public MyClass myBean(){
        // return your bean
    }
}

所有这一切,你的例子确实让我觉得你应该与实体(Car)和存储库合作。如果您正在设计模型图层并且想要将Cars数据存储在数据库中,请参阅Spring Data

答案 1 :(得分:0)

如果您不想使用context.getBean(...),那么您可以使用new Car(...)构建汽车,因为它会产生相同的效果。

这只是两种方式!