Spring核心接口之Ordered

203 阅读3分钟

一、Ordered接口介绍

Spring中提供了一个Ordered接口。从单词意思就知道Ordered接口的作用就是用来排序的。 Spring框架是一个大量使用策略设计模式的框架,这意味着有很多相同接口的实现类,那么必定会有优先级的问题。于是Spring就提供了Ordered这个接口,来处理相同接口实现类的优先级问题。

接口定义

public interface Ordered {
/**
 * Useful constant for the highest precedence value.
 * @see java.lang.Integer#MIN_VALUE
 */
int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;

/**
 * Useful constant for the lowest precedence value.
 * @see java.lang.Integer#MAX_VALUE
 */
int LOWEST_PRECEDENCE = Integer.MAX_VALUE;

/**
 * Get the order value of this object.
 * <p>Higher values are interpreted as lower priority. As a consequence,
 * the object with the lowest value has the highest priority (somewhat
 * analogous to Servlet {@code load-on-startup} values).
 * <p>Same order values will result in arbitrary sort positions for the
 * affected objects.
 * @return the order value
 * @see #HIGHEST_PRECEDENCE
 * @see #LOWEST_PRECEDENCE
 */
int getOrder();

2、OrderComparator类:实现了Comparator接口的一个比较器。

public class OrderComparator implements Comparator<Object> {
/**
 * Shared default instance of OrderComparator.
 */
public static final OrderComparator INSTANCE = new OrderComparator();

public int compare(Object o1, Object o2) {
    boolean p1 = (o1 instanceof PriorityOrdered);
    boolean p2 = (o2 instanceof PriorityOrdered);
    if (p1 && !p2) {
        return -1;
    }
    else if (p2 && !p1) {
        return 1;
    }

    // Direct evaluation instead of Integer.compareTo to avoid unnecessary object creation.
    int i1 = getOrder(o1);
    int i2 = getOrder(o2);
    return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
}

/**
 * Determine the order value for the given object.
 * <p>The default implementation checks against the {@link Ordered}
 * interface. Can be overridden in subclasses.
 * @param obj the object to check
 * @return the order value, or {@code Ordered.LOWEST_PRECEDENCE} as fallback
 */
protected int getOrder(Object obj) {
    return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : Ordered.LOWEST_PRECEDENCE);
}

/**
 * Sort the given List with a default OrderComparator.
 * <p>Optimized to skip sorting for lists with size 0 or 1,
 * in order to avoid unnecessary array extraction.
 * @param list the List to sort
 * @see java.util.Collections#sort(java.util.List, java.util.Comparator)
 */
public static void sort(List<?> list) {
    if (list.size() > 1) {
        Collections.sort(list, INSTANCE);
    }
}

/**
 * Sort the given array with a default OrderComparator.
 * <p>Optimized to skip sorting for lists with size 0 or 1,
 * in order to avoid unnecessary array extraction.
 * @param array the array to sort
 * @see java.util.Arrays#sort(Object[], java.util.Comparator)
 */
public static void sort(Object[] array) {
    if (array.length > 1) {
        Arrays.sort(array, INSTANCE);
    }
}
}

提供了2个静态排序方法:sort(List<?> list)用来排序list集合、sort(Object[] array)用来排序Object数组 可以下OrderComparator类的public int compare(Object o1, Object o2)方法,可以看到另外一个类PriorityOrdered,这个方法的逻辑解析如下:

1. 若对象o1是Ordered接口类型,o2是PriorityOrdered接口类型,那么o2的优先级高于o1
2. 若对象o1是PriorityOrdered接口类型,o2是Ordered接口类型,那么o1的优先级高于o2    
3.其他情况,若两者都是Ordered接口类型或两者都是PriorityOrdered接口类型,调用Ordered接口的getOrder方法
得到order值,order值越大,优先级越小

简单来说就是: OrderComparator比较器进行排序的时候,若2个对象中有一个对象实现了PriorityOrdered接口,那么这个对象的优先级更高。若2个对象都是PriorityOrdered或Ordered接口的实现类,那么比较Ordered接口的getOrder方法得到order值,值越低,优先级越高。

二、用例

import java.util.Map;
import org.springframework.core.Ordered;

public interface Filter extends Ordered{
    public void doFiler(Map<String, String> prams);

}

2、实现接口

import java.util.Map;
@Component
public class LogFilter implements Filter {
    private int order =1;
    public int getOrder() {
        return order;
    }
    public void setOrder(int order) {
        this.order = order;
    }
    public void doFiler(Map<String, String> prams) {
        System.out.println("打印日志");
    }
}
import java.util.Map;
@Component
public class PowerLogFilter implements Filter {
    private int order =2;
    public int getOrder() {
        return order;
    }
    public void setOrder(int order) {
        this.order = order;
    }
    public void doFiler(Map<String, String> prams) {
        System.out.println("权限控制");
    }
}

3、测试进行排序

public static void main(String[] args) throws Exception {
String config = Test.class.getPackage().getName().replace('.', '/') + "/bean.xml";
   ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);
   context.start();
   Map<String, Filter> filters = context.getBeansOfType(Filter.class);
    System.out.println(filters.size());
   List<Filter> f= new ArrayList<Filter>(filters.values());
   OrderComparator.sort(f);
   for(int i=0; i<f.size(); i++){
       Map<String, String> params = new HashMap<String, String>();
       f.get(i).doFiler(params); //按照顺序进行执行
   }
}

参考:

segmentfault.com/a/119000001…