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

发布于 2024-12-25 15:44:19 字数 2041 浏览 1 评论 0原文

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

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

我的问题是演示者应该被注入到视图中,但是演示者应该有一个在当前视图实例中传递的参数构造函数。所以我希望 @Inject-Annotation 能够允许类似 @Inject(this) 的东西,但事实并非如此:-(

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

视图注释:

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

Presenter-Annotation:

@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-Instance:

@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

编辑:更准确地说:我可以使用注释作为装饰师?

I am trying to get a running example of the MVP (Passive-View) Pattern within a JSF2 application using CDI and Annotations.

My goal is to decouple all the relevant projects, meaning that the view resides in a jsf-war-project and the presenter in a separate jar. I am slightly following Adam Biens example on Oracle, but I dont want the presenter to know anything about the view-framework (in this case JSF).

My problem is that the presenter should be injected to the view, but the presenter should have a parameter-constructor that gets passed in the current view-instance. So I was hoping that the @Inject-Annotation would allow something like @Inject(this), but it doesnt :-(

I got around this problem by an init-method with @PostConstruct which calls a setter on the presenter and passes it the the current view. I guess this is the closest I can get according to the CDI-specification...feel free to correct me if I am wrong.

View-Annotation:

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

Presenter-Annotation:

@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-Instance:

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

Now here's my question: can I somehow extract this boilerplate code (init-method) into the annotation (somehow similar to Aspects)? I dont know much about how to write annotations...I usually just use them :-D

EDIT: to be more precise: can I use Annotations as a Decorator?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

许一世地老天荒 2025-01-01 15:44:19

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

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-Instance:

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

The simplest way to achieve what you want would be to lazily inject (to avoid cyclic injection) the view in the presenter. It would look like this :

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-Instance:

@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();
    }
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文