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

}
11-10 17:37