将类引用传递给注入实例的更好方法

时间:2012-01-05 20:10:52

标签: java annotations mvp cdi

我正在尝试使用CDI和Annotations在JSF2应用程序中获取MVP(被动视图)模式的运行示例。

我的目标是将所有相关项目分离,这意味着视图位于jsf-war-project中,而演示者位于单独的jar中。我在Oracle上稍微关注Adam Biens example,但我不希望演示者知道有关视图框架的任何信息(在本例中为JSF)。

我的问题是应该将演示者注入到视图中,但是演示者应该有一个在当前视图实例中传递的参数构造函数。所以我希望@Inject-Annotation会允许类似@Inject(this),但它不会: - (

我通过带有@PostConstruct的init方法解决了这个问题,它调用了presenter上的setter并将其传递给当前视图。我想根据CDI规范,这是我能得到的最接近的......如果我错了,请随时纠正我。

查看-译注:

@Stereotype
@Named
@RequestScoped
@Target(TYPE)
@Retention(RUNTIME)
@Documented
public @interface View {}

演示-译注:

@Stereotype
@Named
@Target(TYPE)
@Retention(RUNTIME)
@Documented
public @interface Presenter {}

Presenter-Instance:

@Presenter
public class BikeGaragePresenter {

    BikeGarageView view;

    protected BikeGaragePresenter(){}

    public BikeGaragePresenter(BikeGarageView view){
        assert view != null;
        this.view = view;
    }


    public void save(){
        System.out.println(view.getOwner());
    }

    public void setView(BikeGarageView view) {
        this.view = view;
    }   
}

查看实例:

@View
public class BikeGarageBB implements BikeGarageView {

    @Inject
    private BikeGaragePresenter presenter;

    @PostConstruct
    public void init(){
        this.presenter.setView(this);
    }

    private String owner;

    public void setOwner(String owner) {
        this.owner = owner;
    }

    @Override
    public String getOwner() {
        return this.owner;
    }

    @Override
    public void displayMessage(String message) {


    }

    public void save(){
        presenter.save();
    }
}

现在这里是我的问题:我可以以某种方式将这个样板代码(init-method)提取到注释中(以某种方式类似于Aspects)吗?我不太了解如何编写注释...我通常只是使用它们:-D

编辑:更准确一点:我可以将Annotations用作装饰器吗?

1 个答案:

答案 0 :(得分:2)

实现您想要的最简单方法是在演示者中懒惰地注入(以避免循环注入)视图。它看起来像这样:

Presenter-Instance:

@Presenter
public class BikeGaragePresenter {

    BikeGarageView view;

    @Inject
    @Any
    Instance<BikeGarageView> viewInstances;

    public BikeGarageView getView()
    {
        return viewInstances.get();
    }       

    public void save(){
        System.out.println(view.getOwner());
    }


}

查看实例:

@View
public class BikeGarageBB implements BikeGarageView {

    @Inject
    private BikeGaragePresenter presenter;

    private String owner;

    public void setOwner(String owner) {
        this.owner = owner;
    }

    @Override
    public String getOwner() {
        return this.owner;
    }

    @Override
    public void displayMessage(String message) {


    }

    public void save(){
        presenter.save();
    }
}