EJB初学日记(3)

今天主要是看了一下拦截器的实现,在EJB3.0里面,实现拦截非常简单.加一个注释就可以了,这样就可以随时监视某个方法的调用了,拦截器可以是拦截某一个方法也可以是拦截一个类的所有方法的.具体如下

 首先写一个拦截器方法,拦截器方法并不需要实现什么接口,只要符合一定的规范就可以了,

规范是:  Object xxxxx(InvocationContext context)throws Exception,其中xxxxx是方法名,可以自己取.然后用@AroundInvoke来注释这个方法

java 代码
  1. /*  
  2.  * MyInterceptor.java  
  3.  *  
  4.  * Created on 2007年9月8日, 上午12:04  
  5.  *  
  6.  * To change this template, choose Tools | Template Manager  
  7.  * and open the template in the editor.  
  8.  */  
  9.   
  10. package lbf.interceptor;   
  11.   
  12. import java.lang.reflect.Method;   
  13. import java.util.Date;   
  14. import javax.interceptor.AroundInvoke;   
  15. import javax.interceptor.InvocationContext;   
  16. import lbf.test1.Person;   
  17.   
  18. /**  
  19.  *  
  20.  * @author Admin  
  21.  */  
  22. public class MyInterceptor {   
  23.        
  24.     /**  
  25.      * Creates a new instance of MyInterceptor  
  26.      */  
  27.     public MyInterceptor() {   
  28.     }   
  29.     @AroundInvoke  
  30.     public Object myInter(InvocationContext context)throws Exception{   
  31.         if(context.getMethod().getName().equals("insertPerson")){   
  32.             System.out.println("插入新的Person被调用了");   
  33.         }else{   
  34.             System.out.println("其它方法被调用了");   
  35.         }   
  36.         return context.proceed();   
  37.     }   
  38. }   

然后,同样是声明远程接口和实现它的类,为了让拦截显得更有效果,我们声明一个实体Bean,把一个实体插入数据库是我们的工作,然后我们再拦截它,看看会怎么样

java 代码
  1. /*  
  2.  * Person.java  
  3.  *  
  4.  * Created on 2007年9月7日, 下午10:46  
  5.  *  
  6.  * To change this template, choose Tools | Template Manager  
  7.  * and open the template in the editor.  
  8.  */  
  9.   
  10. package lbf.test1;   
  11.   
  12. import java.io.Serializable;   
  13. import java.util.Date;   
  14. import javax.persistence.Column;   
  15. import javax.persistence.Entity;   
  16. import javax.persistence.GeneratedValue;   
  17. import javax.persistence.GenerationType;   
  18. import javax.persistence.Id;   
  19. import javax.persistence.Temporal;   
  20. import javax.persistence.TemporalType;   
  21.   
  22. /**  
  23.  * 实体类 Person  
  24.  *   
  25.  * @author Admin  
  26.  */  
  27. @Entity  
  28. public class Person implements Serializable {   
  29.   
  30.     @Id  
  31.     @GeneratedValue(strategy = GenerationType.AUTO)   
  32.     @Column(name="PersonID",nullable=false)   
  33.     private Integer id;   
  34.     @Column(name="PersonName",nullable=false,length=5)   
  35.     private String name;   
  36.     @Column(name="PersonAge")   
  37.     private int age;   
  38.     @Column(name="PersonSex",nullable=false,length=2)   
  39.     private String sex;   
  40.     @Column(name="PersonPhone",nullable=false,length=11)   
  41.     private String phone;   
  42.     @Column(name="PersonAddress",nullable=false,length=50)   
  43.     private String address;   
  44.     @Temporal(value = TemporalType.DATE)   
  45.     @Column(name="PersonBirthday")   
  46.     private Date birthday;   
  47.        
  48.     /** Creates a new instance of Person */  
  49.     public Person() {   
  50.     }   
  51.   
  52.     /**  
  53.      * 获取此 Person 的 id。  
  54.      * @return id  
  55.      */  
  56.     public Integer getId() {   
  57.         return this.id;   
  58.     }   
  59.   
  60.     /**  
  61.      * 将此 Person 的 id 设置为指定的值。  
  62.      * @param id,新建 id  
  63.      */  
  64.     public void setId(Integer id) {   
  65.         this.id = id;   
  66.     }   
  67.   
  68.     /**  
  69.      * 返回对象的散列代码值。该实现根据此对象  
  70.      * 中 id 字段计算散列代码值。  
  71.      * @return 此对象的散列代码值。  
  72.      */  
  73.     @Override  
  74.     public int hashCode() {   
  75.         int hash = 0;   
  76.         hash += (this.id != null ? this.id.hashCode() : 0);   
  77.         return hash;   
  78.     }   
  79.   
  80.     /**  
  81.      * 确定其他对象是否等于此 Person。当且仅当  
  82.      * 参数不为 null 且该参数是具有与此对象相同 id 字段值的 Person 对象时,  
  83.      * 结果才为 true 
  84.      * @param 对象,要比较的引用对象  
  85.      * 如果此对象与参数相同,则 @return true 
  86.      * 否则为 false 
  87.      */  
  88.     @Override  
  89.     public boolean equals(Object object) {   
  90.         // TODO: Warning - this method won't work in the case the id fields are not set   
  91.         if (!(object instanceof Person)) {   
  92.             return false;   
  93.         }   
  94.         Person other = (Person)object;   
  95.         if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) return false;   
  96.         return true;   
  97.     }   
  98.   
  99.     /**  
  100.      * 返回对象的字符串表示法。该实现根据 id 字段  
  101.      * 构造此表示法。  
  102.      * @return 对象的字符串表示法。  
  103.      */  
  104.     @Override  
  105.     public String toString() {   
  106.         return "lbf.test1.Person[id=" + id + "]";   
  107.     }   
  108.   
  109.     public String getName() {   
  110.         return name;   
  111.     }   
  112.   
  113.     public void setName(String name) {   
  114.         this.name = name;   
  115.     }   
  116.   
  117.     public String getSex() {   
  118.         return sex;   
  119.     }   
  120.   
  121.     public void setSex(String sex) {   
  122.         this.sex = sex;   
  123.     }   
  124.   
  125.     public String getPhone() {   
  126.         return phone;   
  127.     }   
  128.   
  129.     public void setPhone(String phone) {   
  130.         this.phone = phone;   
  131.     }   
  132.   
  133.     public String getAddress() {   
  134.         return address;   
  135.     }   
  136.   
  137.     public void setAddress(String address) {   
  138.         this.address = address;   
  139.     }   
  140.   
  141.     public Date getBirthday() {   
  142.         return birthday;   
  143.     }   
  144.   
  145.     public void setBirthday(Date birthday) {   
  146.         this.birthday = birthday;   
  147.     }   
  148.   
  149.     public int getAge() {   
  150.         return age;   
  151.     }   
  152.   
  153.     public void setAge(int age) {   
  154.         this.age = age;   
  155.     }   
  156.        
  157. }   
java 代码,PersonDAO的实现
java 代码
  1. /*  
  2.  * PersonBean.java  
  3.  *  
  4.  * Created on 2007年9月7日, 下午11:10  
  5.  *  
  6.  * To change this template, choose Tools | Template Manager  
  7.  * and open the template in the editor.  
  8.  */  
  9.   
  10. package lbf.test1;   
  11.   
  12. import java.util.List;   
  13. import javax.ejb.Remote;   
  14. import javax.ejb.Stateless;   
  15. import javax.interceptor.Interceptors;   
  16. import javax.persistence.EntityManager;   
  17. import javax.persistence.PersistenceContext;   
  18. import javax.persistence.Query;   
  19. import lbf.interceptor.MyInterceptor;   
  20.   
  21. /**  
  22.  *  
  23.  * @author Admin  
  24.  */  
  25. @Remote(PersonDAO.class)   
  26. @Stateless  
  27. @Interceptors({MyInterceptor.class})   
  28. public class PersonBean implements PersonDAO{   
  29.     @PersistenceContext  
  30.     private EntityManager em;   
  31.     /** Creates a new instance of PersonBean */  
  32.     public PersonBean() {   
  33.     }   
  34.   
  35.     public boolean insertPerson(Person person) {   
  36.         try{   
  37.            em.persist(person);   
  38.         }catch(Exception exe){   
  39.             exe.printStackTrace();   
  40.             return false;   
  41.         }   
  42.         return true;   
  43.     }   
  44.   
  45.     public String getPersonNameByID(int personid) {   
  46.         Person p=em.find(Person.class,personid);   
  47.         return p.getName();   
  48.     }   
  49.   
  50.     public boolean updatePerson(Person person) {   
  51.         try{   
  52.             em.merge(person);   
  53.         }catch(Exception exe){   
  54.             exe.printStackTrace();   
  55.             return false;   
  56.         }   
  57.         return true;   
  58.     }   
  59.   
  60.     public Person getPersonByID(int personid) {   
  61.         return em.find(Person.class,personid);   
  62.     }   
  63.   
  64.     public List getPersonList(int max, int whichpage) {   
  65.            try {    
  66.             int index = (whichpage-1) * max;    
  67.             Query query = em.createQuery("from Person p order by personid asc");    
  68.             List list = query.setMaxResults(max).    
  69.                                 setFirstResult(index).    
  70.                                 getResultList();    
  71.             em.clear();//分离内存中受EntityManager管理的实体bean,让VM进行垃圾回收    
  72.             return list;    
  73.                 
  74.         } catch (Exception e) {    
  75.             e.printStackTrace();    
  76.             return null;    
  77.         }             
  78.     }   
  79.        
  80. }   
java 代码
  1. /*  
  2.  * PersonDAO.java  
  3.  *  
  4.  * Created on 2007年9月7日, 下午11:10  
  5.  *  
  6.  * To change this template, choose Tools | Template Manager  
  7.  * and open the template in the editor.  
  8.  */  
  9.   
  10. package lbf.test1;   
  11.   
  12. import java.util.Date;   
  13. import java.util.List;   
  14.   
  15. /**  
  16.  *  
  17.  * @author Admin  
  18.  */  
  19. public interface PersonDAO {   
  20.        
  21.     public boolean insertPerson(Person person);   
  22.     public String getPersonNameByID(int personid);   
  23.     public boolean updatePerson(Person person);   
  24.     public Person getPersonByID(int personid);   
  25.     public List getPersonList(int max,int whichpage);   
  26. }   

 

所有的类都定义好了,我们现在开始试用拦截器了

我们声明一个主类去调用PersonBean的一些方法

java 代码
  1. /*  
  2.  * Main.java  
  3.  *  
  4.  * Created on 2007年9月7日, 下午10:37  
  5.  *  
  6.  * To change this template, choose Tools | Template Manager  
  7.  * and open the template in the editor.  
  8.  */  
  9.   
  10. package lbf.client;   
  11.   
  12. import java.util.Date;   
  13. import java.util.Properties;   
  14. import javax.naming.InitialContext;   
  15. import lbf.test1.Person;   
  16. import lbf.test1.PersonDAO;   
  17.   
  18. /**  
  19.  *  
  20.  * @author Admin  
  21.  */  
  22. public class Main {   
  23.     private InitialContext ctx;   
  24.     /** Creates a new instance of Main */  
  25.     public Main() {   
  26.         initContext();   
  27.     }   
  28.     private void initContext(){   
  29.         try{   
  30.             Properties props = new Properties();   
  31.             props.setProperty("java.naming.factory.initial",   
  32.                     "org.jnp.interfaces.NamingContextFactory");   
  33.             props.setProperty("java.naming.provider.url""localhost:1099");   
  34.             props.setProperty("java.naming.factory.url.pkgs""org.jboss.naming");   
  35.                
  36.             ctx = new InitialContext(props);   
  37.         }catch(Exception exe){   
  38.             exe.printStackTrace();   
  39.         }   
  40.     }   
  41.     private void doPerson(){   
  42.         try{   
  43.             PersonDAO dao=(PersonDAO)ctx.lookup("PersonBean/remote");   
  44.             Person pp=new Person();   
  45.             pp.setAddress("香莲里33号20C");   
  46.             pp.setAge(20);   
  47.             pp.setBirthday(new Date());   
  48.             pp.setName("千里冰封");   
  49.             pp.setPhone("12536214");   
  50.             pp.setSex("男");   
  51.             System.out.println("成功吗?"+dao.insertPerson(pp));   
  52.         }catch(Exception exe){   
  53.             exe.printStackTrace();   
  54.         }   
  55.     }   
  56.     /**  
  57.      * @param args the command line arguments  
  58.      */  
  59.     public static void main(String[] args) {   
  60.         // TODO code application logic here   
  61.         Main main=new Main();   
  62.         main.doPerson();   
  63.     }   
  64.        
  65. }   

 

 

在我们执行Main的时候,会看到JBOSS的标准输出会输出一句

"插入新的Person被调用了"

如果我们调用其它的方法,就会输出"其它方法被调用了"

到这里,我想到一个问题,我们拦截的时候只是为了输出这句话吗,我能不能拦截一些别的东西呢,比如,我保存Person的时候,如果Person的姓名不合法,我可不可以检查一下,然后再插入别的,或者我直接换掉原来的调用,调用我自己的东西.行吗?还是试一下先吧,我们把myInter方法换成如下的样子

java 代码
  1. @AroundInvoke  
  2.     public Object myInter(InvocationContext context)throws Exception{   
  3.         if(context.getMethod().getName().equals("insertPerson")){   
  4.             System.out.println("插入新的Person被调用了");   
  5.             Method m=context.getMethod();   
  6.             Person person=new Person();   
  7.             person.setAddress("被换成的地址");   
  8.             person.setAge(10);   
  9.             person.setBirthday(new Date());   
  10.             person.setName("被换的名字");   
  11.             person.setPhone("1380606");   
  12.             person.setSex("男");   
  13.           return  m.invoke(context.getTarget(),person);   
  14.         }else{   
  15.             System.out.println("其它方法被调用了");   
  16.         }   
  17.         return context.proceed();   
  18.     }  

加了几句自己的东东,然后直接把要调用的Method取出来,自己去调用它.然后返回它所应该返回的东西

这个时候,你会发现,当你在调用PersonBean上的insertPerson的时候,你自己要插入的Person被我们改了,插入的是我们拦截器里面的Person.

使用拦截器如果只能这样的话,那岂不是也不太好,想像一下,如果我写一个类的时候,没有使用@Interceptors来注释它使用哪个拦截器,后来我又想拦截它了,岂不是要重新注释一下编译一下然后再布署?这样岂不是太麻烦了.有没有别的方法呢

方法当然有,那就是回归到最原始的用XML方法来配置,用XML方法配置以后,就不管你的Bean有没有使用@Interceptors来注释,它都会按照你声明的内容来进行拦截了,这样就比直接用注释灵活性大了很多了.XML的声明如下

xml 代码
  1. xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee"    
  4.          version = "3.0"    
  5.          xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"    
  6.          xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">  
  7.     <assembly-descriptor>  
  8.         <interceptor-binding>  
  9.             <ejb-name>PersonBeanejb-name>  
  10.             <interceptor-class>lbf.interceptor.MyInterceptorinterceptor-class>  
  11.         interceptor-binding>  
  12.     assembly-descriptor>  
  13. ejb-jar>  

这个XML名字叫做ejb-jar.xml,布署的时候,要把它放在META-INF文件夹里面.所有可以用注释来解决的,其实都可以用XML来配置,EJB3.0之前就是因为XML配置太麻烦才被人说的,我们也不希望完全使用XML来配置,但是在有些情况下,用XML来配置确实是比较灵活.不像用注释配置是硬编码class文件里面去的,如果要改的话,还得用源代码重新编译一下.而XML要改就方法多了,改了以后重新打一下包就可以了,所以是选择注释来配置还是XML来配置,就要看具体的要求了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值