今天在看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;
}