Jsf 如何使用CDI和依赖项注入

Jsf 如何使用CDI和依赖项注入,jsf,jakarta-ee,jsf-2,dependency-injection,cdi,Jsf,Jakarta Ee,Jsf 2,Dependency Injection,Cdi,我想在Farma和Pata对象中使用相同的对象“User”。对象用户首先在Farma对象内部初始化。我试图用@inject注释,但Pata中的对象用户的名称为null值。拜托,谁能帮我理解我做错了什么?谢谢! @Named @SessionScoped public class Farma implements Serializable { @Inject private User user; @PostConstruct public void initialize(

我想在Farma和Pata对象中使用相同的对象“User”。对象用户首先在Farma对象内部初始化。我试图用@inject注释,但Pata中的对象用户的名称为null值。拜托,谁能帮我理解我做错了什么?谢谢!

@Named
@SessionScoped
public class Farma implements Serializable {
    @Inject private User user;

    @PostConstruct
    public void initialize(){
         user.setName("MyName");
    }
    // Getters and Setters
}

@Named
@SessionScoped
public class Pata implements Serializable {
    @Inject private  User user;

    public String getFuzzyName() {
        // Here I want to use the object "user" with the name "MyName" to do some logic
    }
    // Getters and Setters
}

public class User implements Serializable {
    private String name;

    // Getters and Setters
你需要了解豆子。默认范围(如果未指定任何范围)是@Dependent范围,这意味着一个对象的存在正好服务于一个客户机(bean),并且与该客户机(bean)具有相同的生命周期

在这种情况下,这意味着Farma中的用户只存在于Farma类中,并在Farma类的生命周期中生存

Pata中的用户是另一个实例,其生命周期与Pata的生命周期相匹配


您需要正确地限定用户对象的范围。

仅限定用户对象的范围不允许您对其进行初始化。 使用“生产者方法”控制bean的创建。 试试这个:

@SessionScoped
public class Pata implements Serializable {
    @Inject
    @SessionUser // inject here using the producer method
    private  User user;

    public String getFuzzyName() {
        return user.getName();
    }
}
@SessionScoped
public class Farma implements Serializable {
    @Produces
    @SessionUser    // qualifier to tie injection points to this method
    @SessionScoped  // to ensure it will be called once per session for any number of injection points
    public User produceUser() {
        System.out.println("Creating user");
        User u = new User();
        u.setName("User");
        return u;
    }
}
////// that's your custom qualifier, it's in a separate file
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface SessionUser {}

// no scopes here, it is defined by the producer method
public class User implements Serializable {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

正如axiopisty所说,添加@Named@SessionScoped是正确的方法

我试过了,效果很好

@Named
@SessionScoped
public class Pata implements Serializable {
    @Inject
    private User user;

    public String getFuzzyName() {
        System.out.println(user.getName());
        return user.getName();
    }

    public User getUser() {
        return user;
    }

    public void setUser(final User user) {
        this.user = user;
    }
}

@Named
@SessionScoped
public class Farma implements Serializable {
    @Inject
    private User user;

    @PostConstruct
    public void initialize() {
        user.setName("MyName");
    }

    // Getters and Setters

    public User getUser() {
        return user;
    }

    public void setUser(final User user) {
        this.user = user;
    }
}


@Named
@SessionScoped
public class User implements Serializable {
    private String name = "Default";

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }
}


<h:outputText value="#{farma}"></h:outputText><br />
<h:outputText value="#{pata}"></h:outputText><br />
<h:outputText value="#{pata.fuzzyName}"></h:outputText>
@Named
@会议范围
公共类Pata实现了可序列化{
@注入
私人用户;
公共字符串getFuzzyName(){
System.out.println(user.getName());
返回user.getName();
}
公共用户getUser(){
返回用户;
}
公共void setUser(最终用户){
this.user=用户;
}
}
@命名
@会议范围
公共类Farma实现了可序列化{
@注入
私人用户;
@施工后
公共无效初始化(){
user.setName(“MyName”);
}
//接球手和接球手
公共用户getUser(){
返回用户;
}
公共void setUser(最终用户){
this.user=用户;
}
}
@命名
@会议范围
公共类用户实现可序列化{
私有字符串name=“Default”;
公共字符串getName(){
返回名称;
}
public void setName(最终字符串名){
this.name=名称;
}
}



试着让用户名为@SessionScoped。我试过了,但没用。Netbeans显示“未找到符合注入条件的已启用bean”。我正在使用JDK6和Glassfish 3。你能在github上发布你的项目吗?很遗憾,我不能。但是,谢谢你的帮助。我在用户对象中只使用了@SessionScoped,而且很有效!非常感谢。嗯,它可能有用,但它真的很脆弱。CDI尽可能懒洋洋地创建bean。因此,在您的代码中,不能保证在访问用户之前调用
Frarma.initialize()
。然而,
@products
确保了
User
始终在您需要时进行初始化。据我所知,问题是在两个CDI bean中使用相同的对象,这是由容器自动提供的。我希望在用户CDIBean中使用PostConstruct方法初始化用户。