Spring 中org.springframework.core.Ordered接口的实战教学

一、引言​

在 Spring 框架的生态系统中,众多组件需要协同工作。有时,我们希望某些组件按照特定的顺序执行,例如在拦截器链、事件监听器等场景下。org.springframework.core.Ordered接口应运而生,它提供了一种简单而有效的方式来定义组件的执行顺序。​

二、Ordered接口概述​

Ordered接口非常简洁,它只包含一个方法:

int getOrder();

该方法返回一个整数值,用于表示组件的顺序。值越小,优先级越高,执行顺序越靠前。Spring 框架中预定义了一些常用的顺序常量,例如:

public interface Ordered {
    int HIGHEST_PRECEDENCE = -2147483648;
    int LOWEST_PRECEDENCE = 2147483647;
}

三、实战场景一:自定义拦截器顺序​

假设我们有一个 Web 应用,需要定义多个拦截器,并且希望它们按照特定的顺序执行。​

(一)创建自定义拦截器​

首先,创建两个实现HandlerInterceptor接口的自定义拦截器,并实现Ordered接口。

自定义拦截器1:

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.core.Ordered;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FirstInterceptor implements HandlerInterceptor, Ordered {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("FirstInterceptor preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("FirstInterceptor postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("FirstInterceptor afterCompletion");
    }

    @Override
    public int getOrder() {
        return 1;
    }
}

自定义拦截器2:

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.core.Ordered;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SecondInterceptor implements HandlerInterceptor, Ordered {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("SecondInterceptor preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("SecondInterceptor postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("SecondInterceptor afterCompletion");
    }

    @Override
    public int getOrder() {
        return 2;
    }
}

(二)配置拦截器​

在 Spring 的配置类中注册并配置这两个拦截器。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new FirstInterceptor())
               .addPathPatterns("/**");
        registry.addInterceptor(new SecondInterceptor())
               .addPathPatterns("/**");
    }
}

当请求到达时,控制台输出结果如下:

FirstInterceptor preHandle
SecondInterceptor preHandle
SecondInterceptor postHandle
FirstInterceptor postHandle
SecondInterceptor afterCompletion
FirstInterceptor afterCompletion

可以看到,FirstInterceptor的preHandle方法先执行,因为它的getOrder()返回值更小,优先级更高。

四、实战场景二:事件监听器顺序​

Spring 的事件驱动模型中,也可以利用Ordered接口来控制事件监听器的执行顺序。​

(一)定义自定义事件

import org.springframework.context.ApplicationEvent;

public class CustomEvent extends ApplicationEvent {

    public CustomEvent(Object source) {
        super(source);
    }
}

(二)创建事件监听器​

创建两个实现ApplicationListener接口的事件监听器,并实现Ordered接口。

事件监听器1:

import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;

public class FirstEventListener implements ApplicationListener, Ordered {

    @Override
    public void onApplicationEvent(CustomEvent event) {
        System.out.println("FirstEventListener received event");
    }

    @Override
    public int getOrder() {
        return 1;
    }
}

事件监听器2:

import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;

public class SecondEventListener implements ApplicationListener, Ordered {

    @Override
    public void onApplicationEvent(CustomEvent event) {
        System.out.println("SecondEventListener received event");
    }

    @Override
    public int getOrder() {
        return 2;
    }
}

(三)发布事件​

在某个服务类中发布自定义事件。

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;

@Service
public class EventPublisherService implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    public void publishCustomEvent() {
        CustomEvent customEvent = new CustomEvent(this);
        applicationEventPublisher.publishEvent(customEvent);
    }
}

当调用publishCustomEvent方法时,控制台输出结果如下:

FirstEventListener received event
SecondEventListener received event

再次验证了Ordered接口对执行顺序的控制。

五、总结​

通过上述两个实战场景,我们深入了解了org.springframework.core.Ordered接口在 Spring 框架中的应用。无论是自定义拦截器还是事件监听器,合理使用Ordered接口可以确保组件按照我们期望的顺序执行,从而提升系统的稳定性和可维护性。在实际项目中,根据业务需求灵活运用这一特性,将有助于构建更加健壮和高效的 Spring 应用。​

你可能感兴趣的:(软件开发,spring,java,前端)