Jersey AOP实现方式
由于Jersey中的AOP是基于HK2框架实现的,所以对应的拦截器的功能也是由HK2框架实现。
现在我们模拟实现一个接口执行时间监控拦截器的功能。
第一步创建api监控注解
@Documented
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiMonitorAnnotation {
}
第二步创建方法拦截器
@ApiMonitorAnnotation
public class ApiMonitorInterceptor implements MethodInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(ApiMonitorInterceptor.class);
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
long startTime = System.currentTimeMillis();
Object object = invocation.proceed();
long endTime = System.currentTimeMillis();
long totalTime = endTime-startTime;
return object;
}
}
第三步创建方法拦截器服务的实现
Jersey在调用方法拦截器的时候,需要InterceptionService的实现。
该接口中有三个方法,在执行对应的接口方法之前会调用getMethodInteceptors()方法,获取对应的拦截器,并执行拦截器。
@Singleton
public class ApiJerseyMonitorInterceptor implements InterceptionService {
private final static Mapmap =new HashMap();
static{
Annotation[] annotations = ApiMonitorInterceptor.class.getAnnotations();
for(Annotation annotation : annotations){
map.put(annotation,new ApiMonitorInterceptor());
}
}
@Override
public Filter getDescriptorFilter() {
return new Filter() {
public boolean matches(Descriptor descriptor) {
return true;
}
};
}
@Override
public List getMethodInterceptors(Method method) {
Annotation[] annotations = method.getAnnotations();
List list =new ArrayList();
for (Annotation annotation :annotations){
if(map.get(annotation) !=null){
list.add(map.get(annotation));
}
}
return list;
}
@Override
public List getConstructorInterceptors(Constructor constructor) {
return null;
}
}
上面代码可以看到,我们是将注解与拦截器绑定,通过方法上的注解,获取方法对应的拦截器,并执行拦截器。
第四步,创建AbstracctBinding对象的实现, 与拦截服务进行绑定,
public class ApiMonitorBindingextends AbstractBinder {
@Override
protected void configure() {
this.bind(ApiJerseyMonitorInterceptor.class).to(InterceptionService.class).in(Singleton.class);
}
}
第五步,定义特征类,用于注册该绑定,使绑定生效
public class ApiMonitorFeatureimplements Feature{
@Override
public boolean configure(FeatureContext context) {
context.register(new ApiMonitorBinding());
return true;
}
}
第六步,ResourceConfig中注册该特征类
register(ApiMonitorFeature.class);
结束。