CDI可以理解为Spring,但其中的一些功能比spring更强大,灵活。本章是个简单的项目示例。推荐有一定基础的看。
@Entity public class User { private @NotNull @Length(min=3, max=25) @Id String username; private @NotNull @Length(min=6, max=20) String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String setPassword(String password) { this.password = password; } }Bean Validation 里面注解可参考http://my.oschina.net/zhaoqian/blog/118458
@Named(' Credentials') @RequestScoped public class CredentialsBean{ private String username; private String password; @NotNull @Length(min=3, max=25) public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @NotNull @Length(min=6, max=20) public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
<h:form> <h:panelGrid columns="2" rendered="#{!login.loggedIn}"> <f:validateBean> <h:outputLabel for="username">Username:</h:outputLabel> <h:inputText id="username" value="#{credentials.username}"/> <h:outputLabel for="password">Password:</h:outputLabel> <h:inputSecret id="password" value="#{credentials.password}"/> </f:validateBean> </h:panelrid> <h:commandButton value="Login" action="#{login.login}" rendered="#{!login.loggedIn}"/> <h:commandButton value="Logout" action="#{login.logout}" rendered="#{login.loggedIn}"/> </h:form>
我们要用session scope bean 维护当前登录用户信息,并提供给上下文的其他Bean使用.
首先定义2个qualifier。用于登录,JPA EntityManager。
@Qualifier @Retention(RUNTIME) @Target({TYPE, METHOD, PARAMETER, FIELD}) public @interface LoggedIn {} @Qualifier @Retention(RUNTIME) @Target({METHOD, PARAMETER, FIELD}) public @interface UserDatabase {}
A:我们需要适配一个类型安全的EntityManager:,作为资源存在于项目中,JPA就可以以inject的方式注入调用。代码如下:
class UserDatabaseProducer { @Produces @UserDatabase @PersistenceContext static EntityManager userDatabase; }
@SessionScoped @Named public class Login implements Serializable { @Inject Credentials credentials; @Inject @UserDatabase EntityManager userDatabase; private User user; public void login() { List<User> results = userDatabase.createQuery( "select u from User u where u.username = :username and u.password = :password") .setParameter("username", credentials.getUsername()) .setParameter("password", credentials.getPassword()) .getResultList(); if (!results.isEmpty()) { user = results.get(0); } else { // perhaps add code here to report a failed login } } public void logout() { user = null; } public boolean isLoggedIn() { return user != null; } @Produces @LoggedIn User getCurrentUser() { return user; } }
现在,其他的Bean就可以随意的注入 qualifiers为:@LoggedIn,type为: User的资源。
如下代码调用:
public class ViewUserBean { @Inject @LoggedIn User currentUser; @Inject @UserDatabase EntityManager docDatabase; public void viewUser() { //........todo } }在页面:
<h:panelGroup rendered="#{login.loggedIn}"> signed in as #{currentUser.username} </h:panelGroup>
最后写出一段相关在实际项目中使用的resources。
import javax.enterprise.context.RequestScoped; import javax.enterprise.inject.Disposes; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Resources { /** * We are using a non JTA managed persistence context, so we cannot inject an EntityManager with @PersistenceContext, * as this would try to inject a container managed EntityManager. */ @PersistenceUnit private EntityManagerFactory entityManagerFactory; @Produces @RequestScoped protected EntityManager createEntityManager() { return entityManagerFactory.createEntityManager(); } protected void closeEntityManager(@Disposes EntityManager entityManager) { if ( entityManager.isOpen() ) entityManager.close(); } // if you using JTA,you can used this // @Produces // @PersistenceContext // EntityManager em; @Produces public Logger produceLog(InjectionPoint injectionPoint) { return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass().getName()); } }在其他Bean就可以直接@inject这样注入使用。会非常方便。
如: @Inject EntityManager em;
@Inject Logger log;
本章用于CDI项目演示。