Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用CDI使单个实例随处可见?_Java_Rest_Jakarta Ee_Singleton_Cdi - Fatal编程技术网

Java 如何使用CDI使单个实例随处可见?

Java 如何使用CDI使单个实例随处可见?,java,rest,jakarta-ee,singleton,cdi,Java,Rest,Jakarta Ee,Singleton,Cdi,我有一份申请。每个用户对应于实体客户端。在会话期间,用户使用其实体 我有JAX-RS+EJB应用程序。我希望这个实体作为一个单例可见并在所有服务中使用。我想用CDI实现它 首先,用户登录到应用程序。登录后,我想从基中获取它的实体并将其分配给一个单例,但没有成功。我尝试了@Singleton annotations javax.inject、@SessionScoped和@ApplicationScoped 我怎么做 //Entity @Entity @SessionScope //or @Sin

我有一份申请。每个用户对应于实体客户端。在会话期间,用户使用其实体

我有JAX-RS+EJB应用程序。我希望这个实体作为一个单例可见并在所有服务中使用。我想用CDI实现它

首先,用户登录到应用程序。登录后,我想从基中获取它的实体并将其分配给一个单例,但没有成功。我尝试了@Singleton annotations javax.inject、@SessionScoped和@ApplicationScoped

我怎么做

//Entity
@Entity
@SessionScope //or @Singlton/@ApplicationScope
class Client { fields }
我想这样做:

//some ejb
@Inject
Client client;
//use entity
我不想在整个应用程序中传输到实例的链接,但我希望它在任何地方都可以使用CDI


或者我需要创建一个单独的ClientDAO,它将成为我的singleton吗?

根据您的评论,您必须使用@SessionScope。如果希望为所有用户提供一个实例,可以使用@Singleton和@ApplicationScope

要解决您的问题:

您希望在用户登录时实例化客户端。因此,当您在登录服务中时,该对象尚未实例化,因此您不能将其@Inject注入登录服务中,您应该记住删除@Inject注释

您需要使用@products注释。当您希望控制类实例化的方式时,可以使用此注释。当CDI容器想要找到客户机类的实现时,如果它找到了一个返回Client并具有@products注释的方法,它将调用该方法,而不仅仅是实例化客户机本身。您应该完成登录业务,然后创建客户端实例,并将其作为成员变量存储在登录服务中。然后在此类中添加一个方法,该方法返回该客户机对象,并用@products注释该方法。登录服务的最终结构如下所示:

您还可以将@products注释放在字段顶部。在这种情况下,CDI容器将使用存储在该字段上的值,而不是调用方法

    @SessionScope
    public class LoginService {
        @Produces
        @SessionScope
        private Client client;

        public void login(String username, String password) {
            //  implement login business

            //  if login is successful
            client = clientEntity;
        }
    }

当然,这应该被视为一种伪代码。我不知道你生意的所有细节。也许您实现逻辑的方式是完全错误的;。但是要解决这个特定的问题,@products应该可以工作。

那么您的意思是所有用户只有一个客户端类实例?因为您是在登录后对其进行初始化的,所以它似乎是用户特定的对象,这意味着它不是单例对象或应用程序作用域。@zaerymoghaddam否,我想在用户处理实体时将其加载到单例对象中。对于每个session-by-singleton object.Thx,很可能这就是我所需要的。但是为什么LoginService中会有@SessionScope呢?因为您将在该变量中存储客户机实例,所以您应该确保不会与其他客户机共享您的LoginService。因此,它还应限于当前会话当前用户。否则,您需要使用所有此类客户机的一种共享映射/列表,或者将它们放在一种缓存/池中,并在producer方法中访问该池。现在我再想想,@RequestScope可能也会起作用。我认为首先尝试一下是值得的。@RequestScope的生命周期是一个HTTP请求。用户在应用程序中发出一个以上的请求。顺便问一下,将客户端对象放入httpSession怎么样?无论我需要什么,我都可以注入httpSession并从那里获取客户端。顺便说一下,我想出了一个新版本。我将有一个singleton@SessionScope客户端对象,我将更改它。当用户单击“确认数据更改”时,我将更新数据-我将获得连接,在数据库中找到实体,并记录从单例到实体的更改。这是工作方法吗?
    @SessionScope
    public class LoginService {
        private Client client;

        public void login(String username, String password) {
            //  implement login business

            //  if login is successful
            client = clientEntity;
        }

        @Produces
        @SessionScope
        public Client clientProducer() {
            return this.client;
        }
    }
    @SessionScope
    public class LoginService {
        @Produces
        @SessionScope
        private Client client;

        public void login(String username, String password) {
            //  implement login business

            //  if login is successful
            client = clientEntity;
        }
    }