【问题标题】:Different instances of an object with a Session or Application scope in JEE7JEE7 中具有 Session 或 Application 范围的对象的不同实例
【发布时间】:2019-01-04 16:37:02
【问题描述】:

我想注入同一对象的不同实例(使用 Session 或 Appplication Scope)。

我想要两个不同的汽车计数器实例(一个用于红色的,一个用于绿色的)。 相反,它会创建对同一对象的两个引用。

我该如何解决这个问题? (将具有 Application Scope 的计数器保留在服务中,由 session Scope 决定)。

RestSession

@Path("/api/session")
@SessionScoped   
public class RestSession implements Serializable {

    @Inject @Contatori
    private IContatore countRedCar;

    @Inject @Contatori
    private IContatore countGreenCar;   

    @Produces("application/json")
    @GET
    @Path("/red")
    public ResultDTO countRed() {
        countRedCar.conta();
        return new ResultDTO(countRedCar.getCount(),countGreenCar.getCount());
    }

    @Produces("application/json")
    @GET
    @Path("/green")
    public ResultDTO countGreen() {

        countGreenCar.conta();

        return new ResultDTO(countRedCar.getCount(),countGreenCar.getCount());
    }
}

联系

package it.paolo.javaee.util;

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
@Contatori
public class Conta implements IContatore{

    private int count;

    public Conta() {
        count=0;
    }

    public int conta() {
        return count+=1;
    }

    public void setCount(int i) {
        count=i;
    }

    public int getCount() {
        return count;
    }
}

IContatore

package it.paolo.javaee.util;

import java.io.Serializable;

public interface IContatore extends Serializable {

    public int conta();

    public void setCount(int i);

    public int getCount();

}

@interface Contatori3

package it.paolo.javaee.util;

import javax.inject.Qualifier;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})
public @interface Contatori3 {
}

【问题讨论】:

  • 可能有错别字:@Contatori@interface Contatori3
  • 您的两次注射都使用相同的限定符@Contatori,因此为您提供相同的实例
  • 书写错误

标签: java java-ee-7 inject apache-tomee


【解决方案1】:

正如 Felks 评论所说,使用这种方法,您可能需要两个单独的限定符注释和两个用于计数器的生成 bean/方法。但是,对于Conta,您似乎只有一个 bean 实现,也许这不一定是最好的方法?

也许你可以试试这样的:

  • 将您的课程 Conta 更改为普通课程,因此没有 bean
  • 创建一个新的@ApplicationScoped bean 来保存所有可能的Contas

这个新的 bean 可能是这样的:

@ApplicationScoped
@Getter
public class Contas {
    private Conta contaRed = new Conta();
    private Conta contaGreen = new Conta();
}

在你的休息时间,注入Contas

@Inject
private Contas contas;

并访问类似:

contas.getContaRed().whatever();

由于Contas 是应用程序范围内的,getContaRed|Green() 将返回相同的红色|绿色计数器,当Contas 注入其他位置时,这些计数器不会再次初始化。

【讨论】:

  • 我正在学习 Java EE 7。一般来说,首选哪种解决方案。当我必须使用同一对象的多个不同实例(具有应用程序或会话范围)时,我该如何设置它?保持的好习惯
  • 没有简短的回答。但是根据您的问题,这是一个意见问题,但大多数情况下您需要解决。当您需要决定实例化哪个对象(或表示该对象的类)时使用限定符:因此,如果您对某些可用的类/接口有多个实现。但是,当您实例化一个类时,您需要考虑是否可以只执行new Xyz() 或者是否需要@Inject。
  • 如果需要使用托管资源实例化对象,则后者适用,在这种情况下不正确。但是你不能声明一些 bean @Application 范围并期望它在每次注入中都是不同的实例:这就是重点:它是应用程序范围的。但是对于我来说,EE 已经有一段时间了。主要是 Spring,所以无论如何你都应该测试我的解决方案,我刚才没有机会测试。
猜你喜欢
  • 2012-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
  • 2013-10-01
  • 1970-01-01
  • 2021-10-17
相关资源
最近更新 更多