2010-12-08 5 views
24

Возможно ли подключить Spring MVC Interceptor с помощью аннотаций, и если да, то может ли кто-нибудь предоставить мне пример того, как это сделать?Можно ли подключить Spring MVC Interceptor с помощью аннотаций?

По проводке через аннотацию Я имею в виду как можно меньше в конфигурации 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, но можно ли также избавиться от строки 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

Насколько я знаю, нет способов настроить перехватчики Spring MVC без XML вообще.

Однако, есть некоторые упрощения с mvc имен в последних версиях Spring 3.0.x (не пружинные 3.0.0!):

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

Смотрите также:

+0

Хороший ответ. Можно ли создать перехватчик, который будет обрабатывать исключения? – fastcodejava 2011-07-19 04:57:44

0

Я не знаю о весенне-АОПЕ, но если вы используете AspectJ с помощью Spring можно использовать @Aspect, @Pointcut, @Advise и многие другие ...

есть также хорошая статья на HOWTO использовать эти аннотации с Spring AOP здесь: http://java-x.blogspot.com/2009/07/spring-aop-with-aspecj-annotations.html

+0

Спасибо, но мы в настоящее время не используем AspectJ, насколько мне известно. Я также хочу избежать использования аспектов, если смогу. – 2010-12-08 16:07:30

72

Наткнулся на этот вопрос во время поиска именно этого. Наконец, я узнал, что он работает весной 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

я реализовал работающее решение с использованием пользовательских @Interceptor аннотацию в духе @Controller аннотацию Спринга :

@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.TYPE}) 
@Documented 
@Component 
public @interface Interceptor { 
    String[] pathPatterns() default {}; 
    String[] excludePathPatterns() default {}; 
} 

Эта аннотация 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, является Спринг бобов, который расширяет WebMvcConfigurerAdapter и реализует BeanPostProcessor для сканирования для пользовательских @Interceptor аннотации и зарегистрировать бобы, имеющие, что anntation как 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; 
    } 
} 

Просто помните, чтобы сканирование приложения пружинный для этого процессора боб для того, чтобы он на самом деле зарегистрировать @Interceptor с.Что-то вроде:

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages = {"org.my.controller", "org.my.utils.processor"}) 
public class WebConfig extends WebMvcConfigurerAdapter {... 
Смежные вопросы