现在AOP是越来越流行了,面向切面的编程,呵呵,似乎比面向对象的编程还要牛一些,在EJB中,就可以利用拦截机制来实现AOP
代码如下:
会话BEAN的 代码
package com.hadeslee.session; import javax.ejb.Stateless; import javax.interceptor.AroundInvoke; import javax.interceptor.Interceptors; import javax.interceptor.InvocationContext; @Stateless public class TestInterceptorBean implements com.hadeslee.session.TestInterceptorRemote { public TestInterceptorBean() { } public void printSth() { System.out.println("原始的输出" ); } @Interceptors ({MyInter.class }) public String sayHello(String string) { return "sayHelloTo: " +string; } @Interceptors ({MyInter.class }) public String who() { System.out.println("原始方法调用了" ); return "原始的WHO" ; } }
拦截机的 代码
package com.hadeslee.session; import javax.interceptor.AroundInvoke; import javax.interceptor.InvocationContext; public class MyInter { public MyInter() { } @AroundInvoke public Object intercepter(InvocationContext ic)throws Exception{ System.out.println("调用方的名字:" +ic.getBean()); System.out.println("调用方的方法:" +ic.getMethod().getName()); if (ic.getMethod().getName().equals("who" )) ic.proceed(); return "就是这个味" ; } }
在这里我们只需要在需要以后更换的方法加上一个注释@javax.interceptor.Interceptors就可以了,你可以指定一个拦截机,也可以指定多个拦截机,这个注释可以修饰类也可以修饰方法,如果放在类前面就表示此类中的所有公共方法都在调用的范围之内,如果是放在方法前面 ,则表示只作用此方法而不作用于其它方法,然后你可以写一个类来实现拦截,当然你也可以在同一个类里面实现拦截,实现拦截的类没什么特殊的地方,只要你拦截的方法遵守如下签名即可
@AroundInvoke public Object XXX(InvocationContext ic)throws Exception{}
其中的XXX可以换成任何字符,,InvocationContext在运行的时候,由系统自动传入,
我觉得一般于拦截的地方都是以后可能会变的方法或者可能会增加功能的方法,所以应该拦截的类还是另写一个会比较好.并且使用中还发现,你可以先在方法或者类中添加@Interceptors注释,但是你指定的类没有实现@AroundInvoke方法,也不要紧,也不会报异常.所以可以先定义这个注释,以后需要的时候再改进@AroundInvoke方法,也挺好的.
在拦截的时候,你可以选择做完自己的事情,继续执行原来的方法,也可以选择就此结束,不让它往下执行了.并且如果方法有返回值的话,你如果返回一个不是同一个类型的对象,那编译也可以过,但是在运行时,会在调用此BEAN的地方抛出一个java.lang.ClassCastException异常.,所以有返回值的拦截一定要小心,如果方法没有返回值,那么你随便返回什么都可以,反正调用方也用不到这个值,这个值到最后应该就被丢弃了.