CDI(Weld)基础<2> JSF+CDI+JPA项目示例

CDI可以理解为Spring,但其中的一些功能比spring更强大,灵活。本章是个简单的项目示例。推荐有一定基础的看。

1.JPA定义(MVC--M)

@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

2.定义一个managedBean(MVC-C)

@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; }
}

3.jsf登录页面(MVC-V)

<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>

4.定义2个qualifier注解

我们要用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;
}

5.开发SessionScope

@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项目演示。

你可能感兴趣的:(CDI(Weld)基础<2> JSF+CDI+JPA项目示例)