介绍下让bean有序执行的方法

我们在用一些设计模式的时候,特别是在java跟spring生态中,有很多基于接口,会有各种不同的实现,此时如果想让实现了同一个接口的一组处理器(bean)能够按顺序处理,会有比较多种方法,这里简单介绍两种实现方式,
我们先定义一个接口

1
2
3
public interface Processor {
void process();
}

然后有两个实现
第一个实现是

1
2
3
4
5
6
7
public class FirstProcessor implements Processor{

@Override
public void process() {
System.out.println("this is " + this.getClass().getSimpleName());
}
}

第二个实现是

1
2
3
4
5
6
7
public class SecondProcessor implements Processor{

@Override
public void process() {
System.out.println("this is " + this.getClass().getSimpleName());
}
}

主要是为了示意,所以就把类名打了出来
我们通过一个http接口来调用下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RestController
public class OrderController {

@Autowired
private List<Processor> processors;

@RequestMapping(value = "/order", method = RequestMethod.GET)
@ResponseBody
public void test() {
for (Processor processor : processors) {
processor.process();
}
}
}

这里通过autowired注解进行注入,此时我们可以运行起来看下执行顺序
看到控制台输出的确是有序的

1
2
this is FirstProcessor
this is SecondProcessor

这个并不是spring这么智能知道我们的想法,只是刚好按字母顺序F在前
比如我们再加两个处理器
第三个

1
2
3
4
5
6
7
8
@Service
public class ThirdProcessor implements Processor{

@Override
public void process() {
System.out.println("this is " + this.getClass().getSimpleName());
}
}

和第四个

1
2
3
4
5
6
7
@Service
public class FourthProcessor implements Processor{
@Override
public void process() {
System.out.println("this is " + this.getClass().getSimpleName());
}
}

然后我们请求下,就发现是

1
2
3
4
this is FirstProcessor
this is FourthProcessor
this is SecondProcessor
this is ThirdProcessor

没有按照我们想要的顺序执行
那么我们可以怎么做呢

方法一 使用order注解

通过spring的org.springframework.core.annotation.Order 注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package org.springframework.core.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Documented
public @interface Order {
int value() default Integer.MAX_VALUE;
}

通过value值来指定顺序,值越小,顺序越靠前
比如我们这

1
2
3
4
5
6
7
8
9
10
11
12
@Service
@Order(value = 1)
public class FirstProcessor implements Processor{
@Service
@Order(value = 2)
public class SecondProcessor implements Processor{
@Service
@Order(value = 3)
public class ThirdProcessor implements Processor{
@Service
@Order(value = 4)
public class FourthProcessor implements Processor{

运行验证下的确是按照我们想要的顺序执行了

1
2
3
4
this is FirstProcessor
this is SecondProcessor
this is ThirdProcessor
this is FourthProcessor

方法二 实现 Ordered 接口

org.springframework.core.Ordered 接口,需要实现 getOrder 方法

1
2
3
4
5
6
public interface Ordered {
int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
int LOWEST_PRECEDENCE = Integer.MAX_VALUE;

int getOrder();
}

我们就在处理器里实现这个接口方法

1
2
3
4
5
6
7
8
9
10
11
12
public class FirstProcessor implements Processor, Ordered {

@Override
public void process() {
System.out.println("this is " + this.getClass().getSimpleName());
}

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

运行下同样可以实现这个效果

1
2
3
4
this is FirstProcessor
this is SecondProcessor
this is ThirdProcessor
this is FourthProcessor