2010-12-08 86 views
24

是否可以使用注释来连接Spring MVC拦截器,如果有的话,是否有人可以为我提供一个如何操作的例子?是否可以使用注释来连接Spring MVC拦截器?

通过通过注释进行连线我指的是尽可能少地在XML配置中进行操作。例如,我在http://www.vaannila.com/spring/spring-interceptors.html找到这个配置文件;

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:interceptors-ref="loggerInterceptor" /> 
<bean id="loggerInterceptor" class="com.vaannila.interceptor.LoggerInterceptor" /> 

你可以在这里配置多少配置?我想像一个@Autowired会删除第2行显式声明bean的需求,但是是否有可能通过注释去掉第1行?

+0

你能澄清吗?你是指Spring MVC拦截器还是AOP拦截器? “接线”是什么意思? – axtavt 2010-12-08 15:36:34

+1

你可能想看到这个http://karthikg.wordpress.com/2009/10/12/athandlerinterceptor-for-spring-mvc/ – ashishjmeshram 2011-04-26 13:37:27

+1

我知道你已经问了几年这个问题,但是@ Markus Kreusch发布了新版本的Spring MVC的正确答案 – 2013-04-25 14:13:27

回答

17

据我所知,没有办法配置没有XML的Spring MVC拦截器。

然而,也有一些简化,同时在Spring 3.0.x中的最新版本mvc命名空间(不是Spring 3.0.0!):

<mvc:interceptors> 
    <bean class="com.vaannila.interceptor.LoggerInterceptor" /> 
</mvc:interceptors> 

参见:

+0

很好的答案。是否有可能创建拦截器来处理异常? – fastcodejava 2011-07-19 04:57:44

0

我不知道春天的AOP但如果你通过Spring使用AspectJ您可以用@Aspect,@Pointcut,@Advise更多...

有也HOWTO一个不错的文章中使用这些注解与弹簧AOP在这里: http://java-x.blogspot.com/2009/07/spring-aop-with-aspecj-annotations.html

+0

谢谢,但据我所知,目前我们还没有使用AspectJ。如果可以,我也想避免使用方面。 – 2010-12-08 16:07:30

72

在正确搜索时发现了这个问题。最后我发现它可以在Spring 3.1中使用@EnableWebMVC和WebMvcConfigurerAdapter。

简单的例子:

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages="webapp.base.package") 
public class WebApplicationConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void addInterceptors(InterceptorRegistry registry) { 
     registry.addInterceptor(new LoggerInterceptor()); 
    } 

} 
-2

像马库斯Kreusch'answers,它也能像这样工作

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages="webapp.base.package") 
public class WebApplicationConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public RequestMappingHandlerMapping requestMappingHandlerMapping() { 
     RequestMappingHandlerMapping RequestMappingHandlerMapping= super.requestMappingHandlerMapping(); 
     Object[] interceptors = new Object[1]; 
     interceptors[0] = new RoleInterceptor(); 
     RequestMappingHandlerMapping.setInterceptors(interceptors); 
     return RequestMappingHandlerMapping; 
    } 

} 
1

我在春天的@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如豆类实现BeanPostProcessorHandlerInterceptor 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 {...