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