本章節深刻講解spring的comparator,使用與細節,幫助你們在項目裏面正確使用comparator。源碼解讀沒法經過文字很詳細的解釋,詮釋。須要讀者屢次閱讀,深刻理解,組織邏輯,大腦慢慢造成整個流程。java
private Comparator<Integer> comparator = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { if(o1 == o2){ return 0; } return o1 > o2?1:-1; } }; public void comparatorTest(){ Random random = new Random(); List<Integer> intList = new ArrayList<>(); for(int i = 0 ; i< 20 ; i++){ intList.add(random.nextInt(40)); } log.info("intList裏面的數據,如今是無序的:" + intList); Collections.sort(intList, comparator); log.info("排序以後的結果:" + intList.toString()); }
結果spring
2018-04-01 11:27:44.455 [main] INFO c.n.b.spring.core.ordere.OrdereTest - intList裏面的數據,如今是無序的:[26, 21, 18, 35, 25, 14, 15, 17, 15, 13, 37, 15, 35, 29, 13, 19, 32, 15, 19, 12] 2018-04-01 11:27:44.479 [main] INFO c.n.b.spring.core.ordere.OrdereTest - 排序以後的結果:[12, 13, 13, 14, 15, 15, 15, 15, 17, 18, 19, 19, 21, 25, 26, 29, 32, 35, 35, 37]
按照上面comparator的流程,在spring中尋找對應的流程。api
spring 裏面comparator的有兩個子類分別是OrderComparator,AnnotationAwareOrderComparator
dom
comparator的子類都會在當前類裏面聲明一個該類的靜態不可變的變量ide
public class OrderComparator implements Comparator<Object> { public static final OrderComparator INSTANCE = new OrderComparator(); }
public class AnnotationAwareOrderComparator extends OrderComparator { public static final AnnotationAwareOrderComparator INSTANCE = new AnnotationAwareOrderComparator(); }
在DefaultListableBeanFactory裏面聲明瞭一個Comparator類型的dependencyComparator變量,用於對bean進行排序post
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { /** Optional OrderComparator for dependency Lists and arrays */ private Comparator<Object> dependencyComparator; }
一旦使用AnnotatedBeanDefinitionReader與ClassPathBeanDefinitionScanner,就會加載AnnotationAwareOrderComparator.net
public class AnnotationConfigUtils { public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } } ..... } }
對BeanFactoryPostProcessor及子類的list接口進行排序code
class PostProcessorRegistrationDelegate { private static void sortPostProcessors(ConfigurableListableBeanFactory beanFactory, List<?> postProcessors) { Comparator<Object> comparatorToUse = null; if (beanFactory instanceof DefaultListableBeanFactory) { comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator(); } if (comparatorToUse == null) { comparatorToUse = OrderComparator.INSTANCE; } Collections.sort(postProcessors, comparatorToUse); } }
在調用getBean,若是是返回結果是List或者是Array.就會進行排序component
private Object resolveMultipleBeans(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) { Class<?> type = descriptor.getDependencyType(); if (type.isArray()) { Class<?> componentType = type.getComponentType(); Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), type); if (getDependencyComparator() != null && result instanceof Object[]) { Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));//這裏會進行排序 } return result; } else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { Class<?> elementType = descriptor.getCollectionType(); if (elementType == null) { return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), type); if (getDependencyComparator() != null && result instanceof List) { Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans));//這裏會進行排序 } return result; } else if (Map.class.isAssignableFrom(type) && type.isInterface()) { } else { return null; } }
OrderComparator的實現很是簡單,按照compare--> doCompare --> getOrder(Object , OrderSourceProvider)--> getOrder(Object )-->findOrder() 循序查看就行了xml
OrderComparator核心代碼
public class OrderComparator implements Comparator<Object> { /** * Shared default instance of {@code OrderComparator}. */ public static final OrderComparator INSTANCE = new OrderComparator(); public Comparator<Object> withSourceProvider(final OrderSourceProvider sourceProvider) { return new Comparator<Object>() { @Override public int compare(Object o1, Object o2) { return doCompare(o1, o2, sourceProvider); } }; } @Override public int compare(Object o1, Object o2) { return doCompare(o1, o2, null); } private int doCompare(Object o1, Object o2, OrderSourceProvider sourceProvider) { boolean p1 = (o1 instanceof PriorityOrdered); boolean p2 = (o2 instanceof PriorityOrdered); // 若是一個PriorityOrdered實現,一個是Ordered實現,PriorityOrdered實現優先Ordered實現 if (p1 && !p2) { return -1; } else if (p2 && !p1) { return 1; } // 當兩個對象都是PriorityOrdered或者Ordered,獲得order值,進行比較 int i1 = getOrder(o1, sourceProvider); int i2 = getOrder(o2, sourceProvider); return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0; } private int getOrder(Object obj, OrderSourceProvider sourceProvider) { Integer order = null; if (sourceProvider != null) { Object orderSource = sourceProvider.getOrderSource(obj); if (orderSource != null && orderSource.getClass().isArray()) { Object[] sources = ObjectUtils.toObjectArray(orderSource); for (Object source : sources) { order = findOrder(source); if (order != null) { break; } } } else { order = findOrder(orderSource); } } return (order != null ? order : getOrder(obj)); } protected int getOrder(Object obj) { Integer order = findOrder(obj);// findOrder是核心,會被子類重寫, return (order != null ? order : Ordered.LOWEST_PRECEDENCE); } /** * 注意這個方法會被子類重寫。主要是調用Ordered實現類 實現的getOrder方法,獲得orderd值 **/ protected Integer findOrder(Object obj) { return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null); } /** * 注意這個方法會被子類重寫 **/ public Integer getPriority(Object obj) { return null; } }
AnnotationAwareOrderComparator核心代碼
public class AnnotationAwareOrderComparator extends OrderComparator { public static final AnnotationAwareOrderComparator INSTANCE = new AnnotationAwareOrderComparator(); protected Integer findOrder(Object obj) { // 調用OrderComparator.findOrder,先識別Ordered接口, Integer order = super.findOrder(obj); if (order != null) { return order; } // 檢查@Order和@Priority各類元素 // Method,AnnotatedElement的對象只會識別@Order if (obj instanceof Class) { return OrderUtils.getOrder((Class<?>) obj); } else if (obj instanceof Method) { Order ann = AnnotationUtils.findAnnotation((Method) obj, Order.class); if (ann != null) { return ann.value(); } } else if (obj instanceof AnnotatedElement) { Order ann = AnnotationUtils.getAnnotation((AnnotatedElement) obj, Order.class); if (ann != null) { return ann.value(); } } else if (obj != null) { order = OrderUtils.getOrder(obj.getClass()); if (order == null && obj instanceof DecoratingProxy) { order = OrderUtils.getOrder(((DecoratingProxy) obj).getDecoratedClass()); } } return order; } public Integer getPriority(Object obj) { Integer priority = null; if (obj instanceof Class) { priority = OrderUtils.getPriority((Class<?>) obj); } else if (obj != null) { priority = OrderUtils.getPriority(obj.getClass()); if (priority == null && obj instanceof DecoratingProxy) { priority = OrderUtils.getOrder(((DecoratingProxy) obj).getDecoratedClass()); } } return priority; } }
OrderUtils
OrderUtils 很簡單負責從class中識別 @Priority 與 @Order註解
public abstract class OrderUtils { private static Class<? extends Annotation> priorityAnnotationType = null; static { try { // 加載 @Priority 註解, priorityAnnotationType = (Class<? extends Annotation>) ClassUtils.forName("javax.annotation.Priority", OrderUtils.class.getClassLoader()); } catch (Throwable ex) { // javax.annotation.Priority not available, or present but not loadable (on JDK 6) } } public static Integer getOrder(Class<?> type) { return getOrder(type, null); } public static Integer getOrder(Class<?> type, Integer defaultOrder) { // @Order 優於 @Priority 識別 Order order = AnnotationUtils.findAnnotation(type, Order.class); if (order != null) { return order.value(); } // 識別 @Priority 註釋 Integer priorityOrder = getPriority(type); if (priorityOrder != null) { return priorityOrder; } return defaultOrder; } public static Integer getPriority(Class<?> type) { if (priorityAnnotationType != null) { Annotation priority = AnnotationUtils.findAnnotation(type, priorityAnnotationType); if (priority != null) { return (Integer) AnnotationUtils.getValue(priority); } } return null; } }
同時存在多個排序實現方式,哪一個方式的值做爲排序的值。Ordered優選級比@Order,@Order優選級@Priority高
@Order(value = -10000) @Priority ( value = 0 ) public class OrderType implements Ordered{ @Override public int getOrder( ) { return 10000; } }
上面的代碼,如何經過AnnotationAwareOrderComparato.findOrde()獲得的值是10000,若是沒有實現Ordered接口,獲得是值是-1000
@Test public void orderTypeTest(){ List<Ordered> list = new ArrayList< Ordered >(); list.add( new OrderType( ) ); list.add( new PriorityOrderedType() ); Collections.sort(list , AnnotationAwareOrderComparator.INSTANCE); System.out.println( list ); } public class OrderType implements Ordered{ @Override public int getOrder( ) { return -1; } public String toString(){ return "Ordered"; } } public class PriorityOrderedType implements PriorityOrdered{ @Override public int getOrder( ) { return 10000; } public String toString(){ return "PriorityOrderedType"; } } [PriorityOrderedType, Ordered]
從上面的代碼,與結果會發現,PriorityOrdered的實現類order值是10000,而Ordered的實現類order值是-10000,理論上來講輸出結果是[Ordered , PriorityOrderedType],爲何出現這種狀況。由於PriorityOrdered接口排序優選Ordered接口(包括@Order, @Priority)