前言
最近在看框架,找到了这个界面。 在这里总结一下。 我想在帮助大家的同时,提高自己。
订单界面概述
Spring框架有这个接口。 名称为Ordered,当联想到我们应用于数据库的Ordered时,很容易想到它的含义是用于排序的。 那么,Spring为什么要定义这样的排序接口呢? 我们知道spring框架使用了很多策略设计模式。 战略设计模式意味着我们同一个界面,有很多不同的实现。 那么多的实现,先执行哪个,后执行哪个? 这会产生排序和优先排序的问题,出现Ordered接口来解决这个问题。
ordered接口正式介绍
首先,让我们从spring的源代码中看到Ordered接口。 源代码如下所示。
公共接口顺序{
int highest _ precedence=-2147483648;
int lowest _ precedence=2147483647;
输入获取顺序(;
}
复制代码
从上面的代码中可以看出,ordered接口的实现非常简单。 具有最高优先级和最低优先级,还提供了获取当前实现类的order值的方法。
在spring的订单上。 值越小,优先级越高;值越大,优先级越低。
订单接口的应用
在介绍完ordered接口之后,我们来看看实际的应用场景。
有典型的场景。 我们知道spring的事务管理是在aop切面上实现的。 我们自己写aop实现的时候,在事务的切断面的同时切断了代码。 spring应该先执行谁呢? 举个具体的例子,写了切换数据源的aspect片。 如果事务在数据源切换之前执行,则数据源切换将失败。 您一定想在执行事务之前执行数据源切换。
于是ordered的应用场景来了。
试着写下一个切面吧。
@Component
@Aspect
publicclasschangedatabaseimplementsordered {
//阻止所有服务操作
@pointcut('execution ) com.color.*.service.*.* () ) )
公共语音点(
}
@before('point ) ) )
公共语音onlyreadpre
datasourcecontextholder.setdata source type (data source type.MySQL );
System.out.println (数据库切换MYSQL );
}
@after('point ) ) )
公共void onlyreadpast (
datasourcecontextholder.setdata source type (data source type.Oracle );
System.out.println (将数据库返回ORACLE );
}
@Override
公共获取订单
返回1;
}
}
复制代码
上面的代码定义了用于阻止所有服务的触点。 然后在执行方法之前将数据库切换到mysql,在执行方法后将数据库切换到oracle。
最后重写了ordered接口的getOrder方法。 在此将order级别设定为1。
这个时候,我们在布置事务切面的时候。 用xml构成订单。
复制代码
如果是使用注入bean的方式,实现直接接口并与上方一样使用就可以了。
这个时候,我们会发现的。 在数据源之间切换的方法总是在事务之前执行。 这将达到我们的目的。
使用订单注释
到目前为止,读者都在想,实现界面太麻烦了,有没有更方便的方法? 当然有。 介绍@Order注释。
让我们看看order注释的源代码。
@ retention (retention policy.runtime ) )。
@target(elementtype.type,ElementType.METHOD,ElementType.FIELD} )
@Documented
公共@ interface order {
int value () default 2147483647;
}
复制代码
的优先顺序最小。
我们使用的时候,给类加order注释就可以了。
我们模拟了两个类,加入了order注释,然后s
pring容器启动的时候,对类进行空参构造函数加载,通过空参构造函数里面的打印情况,我们就可以看到类初始化和执行的顺序。建立我们的第一个order类。
@Component
//使用order属性,设置该类在spring容器中的加载顺序
@Order(1)
public class Order1 {
private final int ORDERED = 1;
public Order1(){
System.out.println(this);
}
@Override
public String toString() {
return "Order1 is loaded @ORDERED=" + ORDERED + "]";
}
}
复制代码
建立我们的第二个order类。
@Component
//使用order属性,设置该类在spring容器中的加载顺序
@Order(2)
public class Order2 {
private final int ORDERED = 2;
public Order2(){
System.out.println(this);
}
@Override
public String toString() {
return "Order2 is loaded @ORDERED=" + ORDERED + "]";
}
}
复制代码
启动spring容器之后,我们看到控制台执行如下结果。
Order1 is loaded @ORDERED=1]
Order2 is loaded @ORDERED=2]
复制代码
orderComparator的介绍
那么我们假如想知道一个类的order的值,或者想比较两个类的order值谁大谁小,这个时候要如何操作呢,Spring贴心的给我们提供了一个类。OrderComparator,通过这个类,我们获得实例后,使用它所提供的getOrder或者compare方法即可实现上述的需求。
我们照例还是先来看一下源码。
public class OrderComparator implements Comparator {
public static final OrderComparator INSTANCE = new OrderComparator();
public OrderComparator() {
}
public Comparator withSourceProvider(OrderComparator.OrderSourceProvider sourceProvider) {
return (o1, o2) -> {
return this.doCompare(o1, o2, sourceProvider);
};
}
public int compare(@Nullable Object o1, @Nullable Object o2) {
return this.doCompare(o1, o2, (OrderComparator.OrderSourceProvider)null);
}
private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderComparator.OrderSourceProvider sourceProvider) {
boolean p1 = o1 instanceof PriorityOrdered;
boolean p2 = o2 instanceof PriorityOrdered;
if (p1 && !p2) {
return -1;
} else if (p2 && !p1) {
return 1;
} else {
int i1 = this.getOrder(o1, sourceProvider);
int i2 = this.getOrder(o2, sourceProvider);
return Integer.compare(i1, i2);
}
}
private int getOrder(@Nullable Object obj, @Nullable OrderComparator.OrderSourceProvider sourceProvider) {
Integer order = null;
if (obj != null && sourceProvider != null) {
Object orderSource = sourceProvider.getOrderSource(obj);
if (orderSource != null) {
if (orderSource.getClass().isArray()) {
Object[] sources = ObjectUtils.toObjectArray(orderSource);
Object[] var6 = sources;
int var7 = sources.length;
for(int var8 = 0; var8 < var7; ++var8) {
Object source = var6[var8];
order = this.findOrder(source);
if (order != null) {
break;
}
}
} else {
order = this.findOrder(orderSource);
}
}
}
return order != null ? order.intValue() : this.getOrder(obj);
}
protected int getOrder(@Nullable Object obj) {
if (obj != null) {
Integer order = this.findOrder(obj);
if (order != null) {
return order.intValue();
}
}
return 2147483647;
}
@Nullable
protected Integer findOrder(Object obj) {
return obj instanceof Ordered ? ((Ordered)obj).getOrder() : null;
}
@Nullable
public Integer getPriority(Object obj) {
return null;
}
public static void sort(List> list) {
if (list.size() > 1) {
list.sort(INSTANCE);
}
}
public static void sort(Object[] array) {
if (array.length > 1) {
Arrays.sort(array, INSTANCE);
}
}
public static void sortIfNecessary(Object value) {
if (value instanceof Object[]) {
sort((Object[])((Object[])value));
} else if (value instanceof List) {
sort((List)value);
}
}
@FunctionalInterface
public interface OrderSourceProvider {
@Nullable
Object getOrderSource(Object var1);
}
}
复制代码
我们先来重点看一下doCompare方法。判断逻辑如下:
若对象o1是Ordered接口类型,o2是PriorityOrdered接口类型,那么o2的优先级高于o1
若对象o1是PriorityOrdered接口类型,o2是Ordered接口类型,那么o1的优先级高于o2
其他情况,若两者都是Ordered接口类型或两者都是PriorityOrdered接口类型,调用Ordered接口的getOrder方法得到order值,order值越大,优先级越小
那么一句话来说就是这样的。
OrderComparator比较器进行排序的时候,若2个对象中有一个对象实现了PriorityOrdered接口,那么这个对象的优先级更高。
若2个对象都是PriorityOrdered或Ordered接口的实现类,那么比较Ordered接口的getOrder方法得到order值,值越低,优先级越高。
再来看一下getOrder方法。
传入一个对象后,通过provider取得原始对象。如果不为空,继续进行判断。
如果是数组对象,对对象进行遍历,得到order后,跳出。如果不是数组则直接获得对象的order。
最后如果order如果不是空,直接返回order的int值,为空的时候,通过findOrder查看,返回的是order的最大值,也就是最低优先级。
protected int getOrder(@Nullable Object obj) {
if (obj != null) {
Integer order = this.findOrder(obj);
if (order != null) {
return order.intValue();
}
}
return 2147483647;
}
复制代码
总结
至此 ordered相关的东西就介绍到此为止,文中难免有不足,希望大家提出指正,感谢。
关于找一找教程网
本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[一文带你了解Spring核心接口Ordered的实现及应用]http://www.zyiz.net/tech/detail-138571.html