今天在看Springsecurity(4.3.x.RELEASE)的WebSecurityConfiguration時,看到AnnotationAwareOrderComparator,就寫下自己的感受。
List-1
private static class AnnotationAwareOrderComparator extends OrderComparator {
private static final AnnotationAwareOrderComparator INSTANCE = new AnnotationAwareOrderComparator();
@Override
protected int getOrder(Object obj) {
return lookupOrder(obj);
}
private static int lookupOrder(Object obj) {
if (obj instanceof Ordered) {
return ((Ordered) obj).getOrder();
}
if (obj != null) {
Class<?> clazz = (obj instanceof Class ? (Class<?>) obj : obj.getClass());
Order order = AnnotationUtils.findAnnotation(clazz, Order.class);
if (order != null) {
return order.value();
}
}
return Ordered.LOWEST_PRECEDENCE;
}
}
如List-1所示,AnnotationAwareOrderComparator繼承了OrderComparator,並覆寫了getOrder方法。來看lookupOrder方法:
- 首先,判斷Object類型的參數是否是Ordered.java,它是個接口,如下List-2所示。
- 如果參數不是Ordered接口,那麼判斷參數是否是Class<?>,如果是Class<?>,那麼取出它上面的註解Order.java;如果參數是對象,那麼先獲取參數的Class<?>,再判斷是否有Order.java註解(如List-3所示),之後調用Order的value()。
- 如果沒有Order註解,那麼返回一個默認值,這個默認值是。
這個小小的類裏面,考慮了很多中情況,代碼的複用性很強,比如可以實現Ordered接口,又或者可以使用Order註解,傳入的可以Class<?>,又可以是對象。
List-2
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();
}
List-3
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Documented
public @interface Order {
/**
* The order value.
* <p>Default is {@link Ordered#LOWEST_PRECEDENCE}.
* @see Ordered#getOrder()
*/
int value() default Ordered.LOWEST_PRECEDENCE;
}