Java中的泛型和依赖注入

时间:2017-07-26 14:47:33

标签: java generics dependency-injection

我正在开发一个使用JAX-RS作为WebLayer的Java EE应用程序。

我试图打破这个问题。所以你看到的代码只是一个抠图。现在一切正常。如您所见,我有UserEndpoint客户端可以创建新用户。完成所有操作后,VerificationService会发送验证邮件。

UserEndpoint

@Path("/users")
@Stateless
public class UserEndpoint {

    @Inject
    @AuthenticatedUser
    private User authenticatedUser;

    @EJB
    private UserDAO userDAO;

    @EJB
    private TokenDAO tokenDAO;

    @Inject
    private PasswordValidator passwordValidator;

    @Inject
    private UserValidator validator;

    @Inject
    private VerificationService verificationService;

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public User createUser(User user) {

        // Validation and Creation

        // Verification
        this.verificationService.sendVerificationMail(user);

        return user;
    }
}

VerificationService

@Singleton
public class VerificationService {

    @Inject
    private MailService mailSender;

    @Inject
    private TemplateService templateService;

    public void sendVerificationMail(User user) {
        this.templateService.setUserTemplate(TemplateCategory.VerificationTemplate, user);
        mailSender.sendMail(new Message(
            MessageDAO.systemEmailAddresses.get(0),
            user.getEmail(),
            templateService.getSubject(),
            templateService.getContent()));
    }
}

因为我想要一个可扩展的项目,所以我决定封装端点的一部分,所以我可以在其他项目中使用它。由于每个用户都必须以这种或那种方式进行验证,我认为验证过程的封装是个好主意。问题是我不知道如何实现这一点。我的第一个方法如下:

CoreUserEndpoint

@Path("/users")
@Stateless
public abstract class CoreUserEndpoint<D extends BaseUserDAO<T>, T extends BaseUser, V extends CoreUserValidator<D, T>> extends EntityEndpoint<D, T, V> {

    @EJB
    private TokenDAO tokenDAO;

    @Inject
    private PasswordValidator passwordValidator;

    @Inject
    private VerificationService<T> verificationService;

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public User createUser(User user) {

        // Validation and Creation

        // Verification
        this.verificationService.sendVerificationMail(user);

        return user;
    }
}

EntityEndpoint

@Stateless
public class EntityEndpoint<D extends CoreDAO<T>, T extends CoreEntity, V extends CoreValidator> {

    protected D entityDAO;

    @Inject
    @AuthenticatedUser
    protected T authenticatedUser;

    protected V entityValidator;

}

VerificationService

@Singleton
public class VerificationService<T extends BaseUser> {

    @Inject
    private MailService mailSender;

    @Inject
    private TemplateService<T> templateService;

    public void sendVerificationMail(User user) {
        this.templateService.setUserTemplate(TemplateCategory.VerificationTemplate, user);
        mailSender.sendMail(new Message(
            MessageDAO.systemEmailAddresses.get(0),
            user.getEmail(),
            templateService.getSubject(),
            templateService.getContent()));
    }
}

当我尝试这个时,我得到了着名的WELD-001408: Unsatisfied dependencies错误。我想我确实理解为什么会这样。在我阅读here时,我无法使用泛型,@Inject@EJB。但是,如果我无法使用泛型,我如何封装项目的核心?他们的任何工作或不同的方法?我相信在互联网的任何地方都已有解决方案。但经过3天的搜索没有取得任何进展,我真的很沮丧,并认为最好问你们。如果你能指出我正确的方向,我真的很感激。

1 个答案:

答案 0 :(得分:0)

我只是想了解逻辑。由于我对问题的评论太长,我决定在aswer部分发帖。

免责声明:它没有直接回答您的问题

所以,让我们开始吧:

  

使用以下格式定义泛型类:

     

class name<T1, T2, ..., Tn> { /* ... */ }类型参数部分,   由尖括号(&lt;&gt;)分隔,在类名后面。它指定   类型参数(也称为类型变量)T1, T2, ..., and Tn

1。通过这样做:

public abstract class CoreUserEndpoint<D extends BaseUserDAO<T>, T extends BaseUser, V extends CoreUserValidator<D, T>>

类型变量D extends BaseUserDAO<T>, T extends BaseUser, V extends CoreUserValidator<D, T>,指示Java编译器为了使用CoreUserEndpoint,需要指定类型。

2. 接下来执行此操作时:

public abstract class CoreUserEndpoint<...> extends EntityEndpoint<D, T, V> 

使用先前定义的类型参数在EntityEndpoint中使用。现在,编译器将查找名为DTV的类(或接口,...)。

这是我不确定的部分。如果编译器从CoreUserEndpoint的声明中找到它们,那么你试图强制该类从多个类扩展,这是不允许的,这样做:

public class EntityEndpoint<D extends CoreDAO<T>, T extends CoreEntity, V extends CoreValidator>

P.S。如果我在这里写的内容有任何意义,我会非常感谢任何反馈,来自Java开发经验。