我在春天的@Controller
标注的精神使用自定义@Interceptor
注解实施了有效的解决方案:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Component
public @interface Interceptor {
String[] pathPatterns() default {};
String[] excludePathPatterns() default {};
}
此注释s HOULD应用于HandlerInterceptor
类型如下所示:
@Interceptor
public class BuildTimestampInterceptor extends HandlerInterceptorAdapter {
private final String buildTimestamp;
public BuildTimestampInterceptor(@Value("${build.timestamp}") String buildTimestamp) {
this.buildTimestamp = buildTimestamp;
}
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
req.setAttribute("buildTimestamp", buildTimestamp);
return true;
}
}
最后,处理器类,InterceptorProcessor
,是一个Spring bean延伸WebMvcConfigurerAdapter
和以扫描为定制@Interceptor
注释和寄存器具有anntation如豆类实现BeanPostProcessor
HandlerInterceptor
S中的覆盖addInterceptors
方法中:
@Component
public class InterceptorProcessor extends WebMvcConfigurerAdapter implements BeanPostProcessor {
private final Map<HandlerInterceptor,Interceptor> interceptors = new HashMap<>();
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
scanForInterceptorAnnotation(bean, beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String string) throws BeansException {
return bean;
}
protected void scanForInterceptorAnnotation(Object bean, String beanName) {
Optional<Interceptor> optionalInterceptor = getInterceptorAnnotation(bean.getClass());
if (optionalInterceptor.isPresent() && bean instanceof HandlerInterceptor) {
interceptors.put((HandlerInterceptor) bean, optionalInterceptor.get());
}
}
private Optional<Interceptor> getInterceptorAnnotation(Class cls) {
Annotation[] annotations = cls.getAnnotationsByType(Interceptor.class);
if (hasValue(annotations)) {
return Optional.of((Interceptor) annotations[0]);
}
return Optional.empty();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
interceptors.forEach((HandlerInterceptor key, Interceptor val) -> {
InterceptorRegistration registration = registry.addInterceptor(key);
if (hasValue(val.pathPatterns())) {
registration.addPathPatterns(val.pathPatterns());
}
if (hasValue(val.excludePathPatterns())) {
registration.excludePathPatterns(val.excludePathPatterns());
}
});
}
private static <T> boolean hasValue(T[] array) {
return array != null && array.length > 0;
}
}
只记得有你的Spring应用程序扫描该处理器豆才能有实际注册@Interceptor
秒。例如:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"org.my.controller", "org.my.utils.processor"})
public class WebConfig extends WebMvcConfigurerAdapter {...
你能澄清吗?你是指Spring MVC拦截器还是AOP拦截器? “接线”是什么意思? – axtavt 2010-12-08 15:36:34
你可能想看到这个http://karthikg.wordpress.com/2009/10/12/athandlerinterceptor-for-spring-mvc/ – ashishjmeshram 2011-04-26 13:37:27
我知道你已经问了几年这个问题,但是@ Markus Kreusch发布了新版本的Spring MVC的正确答案 – 2013-04-25 14:13:27