web-dev-qa-db-ja.com

アノテーションを使用して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行目を削除することもできますか?

28
James McMahon

私の知る限り、XMLなしでSpring MVCインターセプターを構成する方法はまったくありません。

ただし、Spring 3.0.xの最新バージョン(Spring 3.0.0ではありません)には、mvc名前空間の簡略化がいくつかあります。

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

以下も参照してください:

19
axtavt

これを正確に検索しているときにこの質問に遭遇しました。最後に、WebMvcConfigurerAdapterと組み合わせて@EnableWebMVCを使用すると、Spring 3.1で機能することがわかりました。

簡単な例:

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

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

}
75
Markus Kreusch

Springの@Interceptorアノテーションの精神に基づいて、カスタム@Controllerアノテーションを使用して実用的なソリューションを実装しました。

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

この注釈は、次のように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は、カスタム@InterceptorアノテーションをスキャンしてBeanを登録するためにWebMvcConfigurerAdapterを拡張し、BeanPostProcessorを実装するSpring BeanですオーバーライドされたHandlerInterceptorメソッド内のaddInterceptorssとしてのその注釈:

@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;
  }
}

実際に@Interceptorsを登録するために、このアプリケーションBeanをSpringアプリケーションでスキャンすることを忘れないでください。何かのようなもの:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"org.my.controller", "org.my.utils.processor"})
public class WebConfig extends WebMvcConfigurerAdapter {...
3
Brice Roncace

Spring-AOPについては知りませんが、Spring経由でAspectJを使用している場合は、@ Aspect、@ Pointcut、@ Adviseなどを使用できます...

spring AOPでこれらのアノテーションを使用する方法に関する素晴らしい記事もここにあります http://Java-x.blogspot.com/2009/07/spring-aop-with-aspecj-annotations.html

0
fasseg