这是我参与8月更文挑战的第七天,活动详情查看:8月更文挑战
Order规定执行的先后顺序的一个注解,默认值为INT_MAX, 值越低优先级就越搞,并不会影响启动的顺序,影响启动顺序的是依赖关系和@DependsOn有关,也就是说如果想约定启动的顺序可以用@DependsOn来解决,另外接口Ordered也可以实现排序的功能,实现其getOrder方法即可:
public interface Ordered {
int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
// 用法与@Order注解类似,只是一个是注解一个是基于接口
int getOrder();
然后使用OrderUtils抽象工具类进行封装处理,考虑到性能问题,这里spring采用Map的子类ConcurrentReferenceHashMap进行本地缓存。该子类的源码中是这样描述的如果未明确指定,此实现将默认使用软引用(java引用类型)。这种引用类型的作用就是告诉GC,当内存不足时,哪些是不重要的。而软引用类型就是这样的一类。若是回收后,还是内存不足那么才会抛出 OutOfMemory 错误,软引用类型十分适合缓存场景,感兴趣的同学可以试试。ok,我们继续别扯太远了,它最终是通过AnnotationAwareOrderComparator.sort()实现的,而AnnotationAwareOrderComparator继承了OrderComparator类,而OrderComparator又实现了java.util.Comparator接口,从而实现了排序的功能,这也就是它为什么可以进行排序处理的原理。ok,我们来验证下
首先新建子项目,继承父依赖的版本,只导入以下maven包即可
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
/**
* @author dongqin
* @description order注解 比较器测试
* @date 2021/08/06
*/
public class AnnotationAwareOrderComparatorTest {
private final static Log LOG = LogFactory.getLog(AnnotationAwareOrderComparatorTest.class);
private static List<Object> listObject = new ArrayList<>(2);
public static void main(String[] args) {
listObject.add(new Role());
listObject.add(new User());
// 日志输出排序前的结果
doPrintLogByIndex(0);
doPrintLogByIndex(1);
if (LOG.isInfoEnabled()) {
LOG.info("开始执行[AnnotationAwareOrderComparator#sort(List list)]");
}
// 进行排序
AnnotationAwareOrderComparator.sort(listObject);
// 日志输出排序后的结果
doPrintLogByIndex(0);
doPrintLogByIndex(1);
}
/**
* 通过索引打印日志
*
* @param index 索引
*/
public static void doPrintLogByIndex(int index) {
Object o = listObject.get(index);
if (o instanceof User) {
if (LOG.isInfoEnabled()) {
LOG.info(String.format("第[%d]个执行的是类:[%s]", ++ index , User.class.getName()));
}
return;
}
if (LOG.isInfoEnabled()) {
StringBuffer buffer = new StringBuffer();
buffer.append("第[");
buffer.append(++ index);
buffer.append("]个执行的是类:[");
buffer.append(Role.class.getName());
buffer.append("]");
LOG.info(buffer.toString());
}
}
}
@Order(-200)
class User {
@Override
public String toString() {
return "User{}";
}
}
@Order(2)
class Role {
@Override
public String toString() {
return "Role{}";
}
}
运行main方法,结果如下所示
Connected to the target VM, address: '127.0.0.1:20869', transport: 'socket'
八月 07, 2021 12:37:06 上午 com.dqcer.dxptools.core.order.AnnotationAwareOrderComparatorTest doPrintLogByIndex
信息: 第[1]个执行的是类:[com.dqcer.dxptools.core.order.Role]
八月 07, 2021 12:37:06 上午 com.dqcer.dxptools.core.order.AnnotationAwareOrderComparatorTest doPrintLogByIndex
信息: 第[2]个执行的是类:[com.dqcer.dxptools.core.order.User]
八月 07, 2021 12:37:06 上午 com.dqcer.dxptools.core.order.AnnotationAwareOrderComparatorTest main
信息: 开始执行[AnnotationAwareOrderComparator#sort(List list)]
八月 07, 2021 12:37:06 上午 com.dqcer.dxptools.core.order.AnnotationAwareOrderComparatorTest doPrintLogByIndex
信息: 第[1]个执行的是类:[com.dqcer.dxptools.core.order.User]
八月 07, 2021 12:37:06 上午 com.dqcer.dxptools.core.order.AnnotationAwareOrderComparatorTest doPrintLogByIndex
信息: 第[2]个执行的是类:[com.dqcer.dxptools.core.order.Role]
Disconnected from the target VM, address: '127.0.0.1:20869', transport: 'socket'
Process finished with exit code 0
通过实践证明了通过AnnotationAwareOrderComparator.sort()确实能够实现排序功能.