[英]Generics and Dependency Injection in Java
我正在開發將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
錯誤。 而且我想我確實理解為什么會這樣。 正如我在這里閱讀的那樣,我無法使用@Inject
或@EJB
的泛型。 但是,如果我不能使用泛型,該如何封裝項目的核心? 他們有沒有解決的方法或不同的方法? 我相信互聯網上任何地方都已經有解決方案。 但是經過三天的搜索卻沒有取得任何進展,我感到非常沮喪,並認為最好問問你們。 因此,如果您能指出正確的方向,我將不勝感激。
我只是想了解邏輯。 由於我對問題的評論過長,因此我決定將其發布在aswer部分。
免責聲明: 它不會直接回答您的問題
因此,讓我們開始:
通用類以以下格式定義:
class name<T1, T2, ..., Tn> { /* ... */ }
類參數部分由尖括號(<>)分隔,緊隨類名。 它指定類型參數(也稱為類型變量)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
使用的先前定義的類型參數。 現在,編譯器將查找名為D
, T
和V
類(或接口,...)。
這是我不確定的部分。 如果編譯器從您的CoreUserEndpoint
聲明中找到了它們,那么您將試圖通過以下方法強制該類從多個類擴展:
public class EntityEndpoint<D extends CoreDAO<T>, T extends CoreEntity, V extends CoreValidator>
PS:如果我在這里寫的內容有任何見識,我將非常感謝經驗豐富的Java開發人員的任何反饋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.