如何解决强制子类将@Schedule添加到Java Spring中的超抽象类中的方法中
我有一个超级抽象类,该类具有一些常见的实现方法和其他要由子类实现的抽象方法。常用的实现方法之一是被注释为@Scheduled的方法,但是我希望子类定义应如何定义此调度表(固定延迟,固定速率或cron等)。如何实现这种行为?
我想到的一种方法是重写要在子类中调度的方法,以便仅在超类中调用其对应的方法,并在其上添加@Scheduled并带有所需的定义,但我不这样做。不知道如何执行子类操作,因为该方法不是抽象。
超级抽象类
public abstract class SuperClass {
public void x(); // abstract method
public void y() {
// Some implementation
}
// Method to be scheduled.
public void scheduledMethod() {
x();
y();
}
}
子类
public class Subclass extends SuperClass {
public void x() {
// Some implementation
}
// How to enforce the developer to add this ?
@Scheduled(cron = "0 0 0 * * ?")
public void scheduledMethod(){
super.scheduledMethod()
}
}
解决方法
我无法理解如何使用@Scheduled
,但是,我有另一种选择:
- 在您的抽象类中,要求子类实现一个方法以返回时间表:
public String getCronString();
- 使用子类中实现的方法
getCronString()
使用Scheduler以编程方式计划任务,以返回cron计划。很少有关于如何使用Spring Boot编程安排任务的示例:
基本上,如果您的子类未实现public String getCronString();
,则您的代码将无法编译。
一种选择是在 bean 创建时检查 @Scheduled
注释是否存在(或 meta-present)。这可以通过在超类的 @PostConstruct
方法中使用反射轻松实现:
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ClassUtils;
public abstract class SuperClass {
...
@PostConstruct
public void enforceScheduling() {
boolean annotationPresent = AnnotationUtils.getAnnotation(ClassUtils.getMethod(getClass(),"scheduledMethod"),Scheduled.class) != null;
if (!annotationPresent) {
throw new IllegalStateException("@Scheduled annotation missing from scheduledMethod");
}
}
}
当 Spring 尝试创建 bean 时,这将导致在应用程序启动时抛出异常,快速失败并且很明显缺少什么。
,我过去在对类层次结构有约束的项目中做过的一件事是编写一个单元测试,该测试遍历类的每个具体(非抽象)实例并检查它是否满足该约束。
由于这是使用 Spring,我们可能更关心这种类型的每个 bean 是否匹配约束,而不是类路径上的每个子类是否匹配。
这种情况下的约束是在子类中的给定方法上存在 @Scheduled
注释(或 meta-present)。给定子类的 Class
对象,可以使用反射轻松实现注解的存在。
综合起来,我们可以使用这种技术编写单元测试:
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ClassUtils;
@SpringBootTest
public class SuperClassTest {
@Autowired
private List<SuperClass> beansOfThisType;
@Test
public void allBeansMustBeScheduled() {
for (SuperClass bean : beansOfThisType) {
boolean annotationPresent = AnnotationUtils.getAnnotation(ClassUtils.getMethod(bean.getClass(),Scheduled.class) != null;
assertTrue(annotationPresent,"@Scheduled annotation missing from scheduledMethod for " + bean.getClass());
}
}
}
检查类路径上类型的每个对象而不仅仅是 Spring bean 是一种非常相似的方法;不同之处在于获取要检查的 Class
对象列表的机制。从类路径中获取匹配的对象不够直接,超出了本答案的范围。 How do you find all subclasses of a given class in Java? 列出了多种实现方式。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。