记录:275
场景:应用org.springframework.core.Ordered接口,从spring的IOC容器中取出bean实例,按照指定顺序执行bean的指定方法,比如初始化方法。执行顺序取Ordered接口实现类的getOrder方法返回值,按照从小到大排序,依次执行。本例按照从小到大,具体按需即可。
版本:Spring Boot 2.6.3
一、案例场景
1.三个类A、B、C都实现Ordered接口,并有init方法。
2.Spring容器加载完成A、B、C三个类后,需要按照指定顺序调用init方法。
3.本例调用init方法顺序是,C、B、A。
4.分别对A、B、C实现类的getOrder返回值设置为1223、1222、1221。
二、使用类
org.springframework.core.Ordered,排序接口。
java.util.ArrayList,在List中是按照写入顺序存放。
org.springframework.beans.factory.InitializingBean,初始化接口。允许一个bean在它的所有必须属性被BeanFactory设置后,来执行初始化的工作。实现afterPropertiesSet方法。
org.springframework.beans.factory.DisposableBean,销毁接口。允许在容器销毁该bean的时候获得一次回调。实现destroy方法。
org.springframework.util.CollectionUtils,有相关对集合的操作,比如isEmpty判断Map是否为空,判断Collection是否为空。
java.util.Collections,一个集合类,本例使用sort方法对入参的List进行排序,排序规则依据Comparator实现类。
java.util.Comparator,一个比较器接口,本例实现compare方法,排序List中对象顺序。
三、代码
1.IExampleOrdered接口
IExampleOrdered接口,继承Ordered。
public interface IExampleOrdered extends Ordered {
void init();
String getInitName();
}
2.AbstractExampleOrdered抽象类
AbstractExampleOrdered抽象类,实现IExampleOrdered接口。
public abstract class AbstractExampleOrdered
implements IExampleOrdered {
@Override
public String getInitName() {
return this.getClass().getSimpleName();
}
}
3.OrderedUtils工具类
OrderedUtils排序和调用实现类的init工具类。
@Slf4j
public class OrderedUtils {
private static final List<IExampleOrdered> beanList = new ArrayList<>();
/**
* spring已经初始化过得bean添加到List中
*/
public static void addBean(IExampleOrdered exampleOrdered) {
if (exampleOrdered == null) return;
beanList.add(exampleOrdered);
}
public static List<IExampleOrdered> getBeanList() {
return beanList;
}
public static void handleBeans() {
if (!CollectionUtils.isEmpty(beanList)) {
// 使用的Collections.sort排序,取值是Ordered接口的getOrder()值
Collections.sort(beanList, new handleComparator());
log.info("handleBeans开始执行.");
// 排序后getOrder()值更小的放在List更靠前位置
for (IExampleOrdered exampleOrdered : beanList) {
String printInfo = String.format("类: %s, getOrder值: %s",
exampleOrdered.getInitName(),
exampleOrdered.getOrder());
try {
log.info(printInfo + ",执行.");
exampleOrdered.init();
} catch (Exception e) {
log.info(printInfo + ",异常.");
e.printStackTrace();
}
}
log.info("handleBeans执行完成.");
}
}
private static class handleComparator implements Comparator<IExampleOrdered> {
@Override
public int compare(IExampleOrdered o1, IExampleOrdered o2) {
return o1.getOrder() - o2.getOrder();
}
}
public static void clear() {
if (beanList.size() > 0) {
beanList.clear();
}
}
}
4.HandleWorker
HandleWorker,实现InitializingBean和DisposableBean接口。本类由spring容器加载。触发调用实现Ordered排序接口的类的init方法。
@Slf4j
@Component
public class HandleWorker implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
log.info("HandleWorker->afterPropertiesSet开始执行.");
try {
ApplicationContext appContext = SpringUtil.getApplicationContext();
Map<String, IExampleOrdered> beans = appContext.getBeansOfType(IExampleOrdered.class);
if (!CollectionUtils.isEmpty(beans)) {
Set<Map.Entry<String, IExampleOrdered>> entrySet = beans.entrySet();
for (Map.Entry<String, IExampleOrdered> map : entrySet) {
// 取出所有IExampleOrdered接口实现类
OrderedUtils.addBean(map.getValue());
}
// 测试使用
printBeanList();
// 依次执行IExampleOrdered接口实现类的init函数
OrderedUtils.handleBeans();
}
} catch (Exception e) {
e.printStackTrace();
}
log.info("HandleWorker->afterPropertiesSet完成.");
}
@Override
public void destroy() throws Exception {
log.info("HandleWorker->destroy开始执行.");
OrderedUtils.clear();
log.info("HandleWorker->destroy完成.");
}
// 测试验证
private void printBeanList() {
List<IExampleOrdered> beanList = OrderedUtils.getBeanList();
log.info("处理前beanList排序:");
for (IExampleOrdered var : beanList) {
String printInfo = String.format("类: %s, getOrder值: %s",
var.getInitName(),
var.getOrder());
log.info(printInfo);
}
}
}
5.排序接口实现类
Ordered接口实现类ExampleStepServiceA、ExampleStepServiceB、ExampleStepServiceC。区别在于getOrder()获取的值不一样。
5.1 ExampleStepServiceA
ExampleStepServiceA类,getOrder()返回值:1223。
@Component
@Slf4j
public class ExampleStepServiceA
extends AbstractExampleOrdered {
@Override
public void init() {
log.info("ExampleStepServiceA->init,执行.");
}
@Override
public int getOrder() {
return 1223;
}
}
5.2 ExampleStepServiceB
ExampleStepServiceB类,getOrder()返回值:1222。
@Component
@Slf4j
public class ExampleStepServiceB
extends AbstractExampleOrdered {
@Override
public void init() {
log.info("ExampleStepServiceB->init,执行.");
}
@Override
public int getOrder() {
return 1222;
}
}
5.3 ExampleStepServiceC
ExampleStepServiceC类,getOrder()返回值:1221。
@Component
@Slf4j
public class ExampleStepServiceC extends AbstractExampleOrdered {
@Override
public void init() {
log.info("ExampleStepServiceC->init,执行.");
}
@Override
public int getOrder() {
return 1221;
}
}
6.测试
6.1 启动日志
HandleWorker的InitializingBean的afterPropertiesSet方法触发调用。
6.2 关闭日志
HandleWorker的DisposableBean的destroy方法触发调用。
以上,感谢。
2022年6月17日