一、前言
CDI作为一个规范,必然会有属于自己的组件应用,比如组件的拦截器。
二、拦截器的作用原理
- 声明拦截器,加@Interceptor注解
方法有二:
1)为拦截器添加Qualifier;
2)不添加Qualifier。 - 为拦截器添加具体的拦截方法,该方法加@AroundInvoke注解
- 在beans.xml文件中声明拦截器的位置
- 调用、注入拦截器
方法有二:
1)使用Qualifier声明注入的拦截器;
2)使用注解@Interceptors(xxx.class)来声明注入的拦截器。
三、拦截器的使用配置
3.1 声明拦截器--添加@Interceptor注解
package cn.edu.sdut.r314;
import java.io.Serializable;
import java.util.Date;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@Interceptor
public class MyInterceptor implements Serializable {
public MyInterceptor() {
}
}
3.2 为拦截器添加具体的实现方法--添加@AroundInvoke注解
@AroundInvoke
public Object doMy(InvocationContext ctx) throws Exception {
System.out.println("MyInterceptor is called at: " + new Date());
return ctx.proceed();
}
3.3 在beans.xml文件中声明该组件拦截器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>cn.edu.sdut.r314.MyInterceptor</class>
</interceptors>
</beans>
3.4 调用、注入拦截器
package cn.edu.sdut.r314;
import javax.inject.Named;
import javax.interceptor.Interceptors;
/**
*
* @author gaoziqiang
*/
@Named
public class RoomController {
/**
* 订房
* @return
*/
public void checkin(){
System.out.println("checkin room......");
}
/**
* 退房
* @return
*/
//拦截器注入方式一
//@My
//拦截器注入方式二
@Interceptors(MyInterceptor.class)//表示拦截器所在的类
public void checkout(){
System.out.println("checkout room......");
}
}
四、代码设计
拦截器及实现方法:
package cn.edu.sdut.r314;
import java.io.Serializable;
import java.util.Date;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@My
@Interceptor
public class MyInterceptor implements Serializable {
public MyInterceptor() {
}
@AroundInvoke
public Object doMy(InvocationContext ctx) throws Exception {
System.out.println("MyInterceptor is called at: " + new Date());
return ctx.proceed();
}
}
beans.xml文件声明:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>cn.edu.sdut.r314.MyInterceptor</class>
</interceptors>
</beans>
注入组件拦截器:
package cn.edu.sdut.r314;
import javax.inject.Named;
import javax.interceptor.Interceptors;
/**
*
* @author gaoziqiang
*/
@Named
public class RoomController {
/**
* 订房
* @return
*/
public void checkin(){
System.out.println("checkin room......");
}
/**
* 退房
* @return
*/
//拦截器声明方式一
//@My
//拦截器声明方式二
@Interceptors(MyInterceptor.class)//表示拦截器所在的类
public void checkout(){
System.out.println("checkout room......");
}
}
为该拦截器添加Qualifier:
package cn.edu.sdut.r314;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;
/**
*
* @author gaoziqiang
*/
@InterceptorBinding
@Target({TYPE,METHOD})
@Retention(RUNTIME)
public @interface My {
}
五、小总结
- 调用注解的位置
1)在Controller类上,则该Controller类的所有方法都会被该拦截器拦截;
实例代码:
package cn.edu.sdut.r314;
import javax.inject.Named;
import javax.interceptor.Interceptors;
/**
*
* @author gaoziqiang
*/
@Named
@My //若拦截器注入到这里,则该类的所有方法都会被拦截
public class RoomController {
/**
* 订房
* @return
*/
public void checkin(){
System.out.println("checkin room......");
}
/**
* 退房
* @return
*/
//拦截器声明方式一
//@My
//拦截器声明方式二
@Interceptors(MyInterceptor.class)//表示拦截器所在的类
public void checkout(){
System.out.println("checkout room......");
}
}
2)在Controller类的具体方法上,则该方法被该拦截器拦截。
2.注解的优先级
1)使用拦截器的Qualifier;
2)使用@Interceptors(xxx.class),即拦截器所在的类;
3)方法2)优先于方法1)。
实例代码:
/**
* 退房
* @return
*/
//拦截器声明方式一
//@My
//拦截器声明方式二
@Interceptors(MyInterceptor.class)//表示拦截器所在的类
public void checkout(){
System.out.println("checkout room......");
}
六、完整实例
详细、完整代码参加github代码库,使用命令部署运行即可。
命令:
mvn clean package wildfly:deploy