Chapter 2: In-depth interpretation of the comparator of spring-core

foreword

This chapter explains in depth the comparator, usage and details of spring, to help you use the comparator correctly in your project. Source code interpretation cannot be explained and interpreted in great detail through text. It requires readers to read many times, deeply understand, organize logic, and the brain slowly forms the whole process.

From in-depth understanding of comparator in java api, form a technical blueprint in mind

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());
}

result

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]

  1. Implementation class of comparator is required
  2. instantiate a subclass of comparator
  3. save instantiation result
  4. Call Collections.sort(intList, comparator); trigger sorting

Process analysis

According to the process of the comparator above, find the corresponding process in spring.

The implementation class of comparator is required, and the basic system

There are two subclasses of comparator in spring, OrderComparator and AnnotationAwareOrderComparatorEnter image description

instantiate a subclass of comparator

Subclasses of comparator will declare a static immutable variable of this class in the current class

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();
}

save instantiation result

A dependencyComparator variable of type Comparator is declared in DefaultListableBeanFactory to sort beans

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
		
	/** Optional OrderComparator for dependency Lists and arrays */
	private Comparator<Object> dependencyComparator;
}

AnnotationAwareOrderComparator is loaded once AnnotatedBeanDefinitionReader is used with ClassPathBeanDefinitionScanner

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);
			}
		}
	.....
	}
}

Call Collections.sort(intList, comparator) to trigger sorting

Sort the list interface of BeanFactoryPostProcessor and subclasses

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);
	}
}

When calling getBean, if the return result is List or Array, it will be sorted

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;
		}
	}

comparator analysis

The implementation of OrderComparator is very simple, just follow the order of compare--> doCompare --> getOrder(Object , OrderSourceProvider)--> getOrder(Object )-->findOrder()

Enter image description

OrderComparator core code

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 core code

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 is simply responsible for identifying @Priority and @Order annotations from the class

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;
	}

}

Summarize

Ordered related objects summary

  1. Classes with the following interfaces and annotations will be sorted by default
    1. PriorityOrdered
    2. Ordered
    3. @Order
    4. @Priority
  2. OrderComparator负责PriorityOrdered,Ordered
  3. AnnotationAwareOrderComparator负责@Order, @Priority
  4. AnnotationAwareOrderComparator will only be loaded when action scanning is enabled in xml or using AnnotatedBeanDefinitionReader and ClassPathBeanDefinitionScanner

Only objects of the same type will be sorted

  1. Sort BeanFactoryPostProcessor, and subclasses
  2. When calling getBean, if the return result is List or Array, it will be sorted
  3. ConfigurationClassParser.processDeferredImportSelectors sort @Impor
  4. AspectJ is also aop

Identify priorities

There are multiple sorting implementations at the same time, and the value of which method is used as the sorting value. Ordered priority is higher than @Order, @Order priority @Priority

@Order(value = -10000)
@Priority ( value = 0 )
public class OrderType implements Ordered{

	@Override
	public int getOrder( ) {
		return 10000;
	}
}

In the above code, how can the value obtained through AnnotationAwareOrderComparato.findOrde() be 10000, if the Ordered interface is not implemented, the value obtained is -1000

Sort priority

	@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]

From the above code and the result, it will be found that the order value of PriorityOrdered's implementation class is 10000, while the order value of Ordered's implementation class is -10000. In theory, the output result is [Ordered, PriorityOrderedType], why does this happen. Because PriorityOrdered interface ordering prefers Ordered interface (including @Order, @Priority)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325028202&siteId=291194637