EJB3.0中拦截器的实现

      拦截器的概念大家肯定不陌生。从字面而言,拦截你行为,至于如何获取你的行为,那就是拦截器的原理——通过反射获取你下一步的操作。

      在面向切面编程中,其实就是在你的方法之前或之后调用方法。比如动态代理就是拦截器的实现的代表。

      既然如此,想想使用动态代理的例子,都可以使用拦截器。比如权限,事务,以及日志。在调用具体的业务之前或之后,打印一条日志到日志文件和数据库中。而不是每次都在代码中重复写代码。

      日志操作,在上篇博客中我们已经提到,上篇博客我们是使用spring来配置aop,而这篇博客跟大家介绍EJB拦截器。其实,拦截器的原来了解后,至于EJB也好,Struts2也好,这只是具体的形式实现,来加强对拦截器的理解。

     在EJB3.0中,拦截器可以作为一个外部类而言,当然也可以作为某类中一个方法。

     第一种:作为外部类而言:

     在EJB项目中:  

package ejb;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class HelloInterceptor {
	//使用@AroundInvoke注释,指定了要做拦截器的方法。
	//使用此注释的格式必须遵守public Object XXX(InvocationContext ctx)throws Exception
	@AroundInvoke
	public Object log(InvocationContext ctx) throws Exception{
		System.out.println("interceptor.....");
		System.out.println("此时执行的方法:"+ctx.getMethod().getName());
		Object obj=ctx.proceed();
		System.out.println(ctx.getMethod().getName()+"已经执行成功。");
		return obj;
	}

}
     其中注释AroundInvoke说明此是作为拦截器的方法,将会调用此拦截器的此方法。

package ejb;
public interface HelloChinaRemote {
   public String sayHello(String name);
   public String Myname();
}
    具体的实现:   

package ejb;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

@Stateless
@Remote
@Interceptors({HelloInterceptor.class})
public class HelloChinaBean implements HelloChinaRemote {

	public String Myname() {
		// TODO Auto-generated method stub
		return "我是釜山人";
	}

	public String sayHello(String name) {
		// TODO Auto-generated method stub
		return name+"我是来自中国。";
	}

}
    客户端新建java项目,把ejb项目引入或这把接口打包。因为客户端需要知道EJB端的接口。

package ejb;
import javax.naming.InitialContext;
public class HelloManagerClient {
	public static void main(String[] args) throws Exception{
		InitialContext context=new InitialContext();
		HelloChinaRemote hello=(HelloChinaRemote)context.lookup("HelloChinaBean/remote");
		hello.Myname();
		hello.sayHello("test");
	}

}
   记得在客户端src下添加jndi.properties文件:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost
java.naming.factory.url.pkgs=org.jboss.naming
   测试结果如下:

13:09:01,312 INFO  [STDOUT] interceptor.....
13:09:01,312 INFO  [STDOUT] 此时执行的方法:Myname
13:09:01,312 INFO  [STDOUT] Myname已经执行成功。
13:09:01,323 INFO  [STDOUT] interceptor.....
13:09:01,323 INFO  [STDOUT] 此时执行的方法:sayHello
13:09:01,323 INFO  [STDOUT] sayHello已经执行成功。
   第二种:某类中某方法

   不必写外部类:HelloInterceptor

   而是直接在我们sessionbean中写方法:【为了方便我们测试,我们又新建一个类】

package ejb;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptors;
import javax.interceptor.InvocationContext;

@Stateless
@Remote
public class HelloChinaBeanInner implements HelloChinaRemote {

	public String Myname() {
		// TODO Auto-generated method stub
		return "我是釜山人";
	}

	public String sayHello(String name) {
		// TODO Auto-generated method stub
		return name+"我是来自中国。";
	}
	
	//使用@AroundInvoke注释,指定了要做拦截器的方法。
	//使用此注释的格式必须遵守public Object XXX(InvocationContext ctx)throws Exception
	@AroundInvoke
	public Object log(InvocationContext ctx) throws Exception{
		System.out.println("interceptor.....");
		System.out.println("此时执行的方法:"+ctx.getMethod().getName());
		Object obj=ctx.proceed();
		System.out.println(ctx.getMethod().getName()+"已经执行成功。");
		return obj;
	}

}
    客户端,我们就不用写了,如上述。【若是按照上述测试,记得更改客户端的jndi名字】

    至于第一种方式和第二种方式区别。

    第一种方式:虽然多写一个外部类,但是耦合度弱。

    第二种方式:在同一个类中,耦合度关联强。

你可能感兴趣的:(EJB3.0中拦截器的实现)