feat: enhance @PostConstruct with order and @Qualifier for fields
- Add value() to @PostConstruct for execution order control - Allow @Qualifier on fields for use with @Inject - Sort @PostConstruct methods by inheritance depth then order value Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -253,22 +253,37 @@ public class BeanScanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<Method> findPostConstructs(Class<?> clazz) {
|
private List<Method> findPostConstructs(Class<?> clazz) {
|
||||||
List<Method> methods = new ArrayList<>();
|
// 收集所有 @PostConstruct 方法及其元数据(继承深度、order 值)
|
||||||
|
record PostConstructInfo(Method method, int depth, int order) {}
|
||||||
|
List<PostConstructInfo> collected = new ArrayList<>();
|
||||||
Class<?> currentClass = clazz;
|
Class<?> currentClass = clazz;
|
||||||
|
int depth = 0;
|
||||||
|
|
||||||
// 从当前类向上遍历到 Object,收集所有 @PostConstruct 方法
|
// 从当前类向上遍历到 Object,收集所有 @PostConstruct 方法
|
||||||
while (currentClass != null && currentClass != Object.class) {
|
while (currentClass != null && currentClass != Object.class) {
|
||||||
|
int currentDepth = depth;
|
||||||
for (Method method : currentClass.getDeclaredMethods()) {
|
for (Method method : currentClass.getDeclaredMethods()) {
|
||||||
if (method.isAnnotationPresent(PostConstruct.class)) {
|
if (method.isAnnotationPresent(PostConstruct.class)) {
|
||||||
if (method.getParameterCount() != 0) {
|
if (method.getParameterCount() != 0) {
|
||||||
throw new InjectException("@PostConstruct method must have no parameters: %s".formatted(method.getName()));
|
throw new InjectException("@PostConstruct method must have no parameters: %s".formatted(method.getName()));
|
||||||
}
|
}
|
||||||
// 添加到列表头部,确保父类方法先执行
|
int order = method.getAnnotation(PostConstruct.class).value();
|
||||||
methods.addFirst(method);
|
collected.add(new PostConstructInfo(method, currentDepth, order));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentClass = currentClass.getSuperclass();
|
currentClass = currentClass.getSuperclass();
|
||||||
|
depth++;
|
||||||
}
|
}
|
||||||
return methods;
|
|
||||||
|
// 先按继承深度降序(父类深度大,先执行),同层级内按 order 升序
|
||||||
|
collected.sort((a, b) -> {
|
||||||
|
int depthCompare = Integer.compare(b.depth, a.depth);
|
||||||
|
if (depthCompare != 0) {
|
||||||
|
return depthCompare;
|
||||||
|
}
|
||||||
|
return Integer.compare(a.order, b.order);
|
||||||
|
});
|
||||||
|
|
||||||
|
return collected.stream().map(PostConstructInfo::method).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,4 +13,11 @@ import java.lang.annotation.Target;
|
|||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface PostConstruct {
|
public @interface PostConstruct {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行顺序,数值越小越先执行,默认为 0
|
||||||
|
*
|
||||||
|
* @return 执行顺序
|
||||||
|
*/
|
||||||
|
int value() default 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import java.lang.annotation.Target;
|
|||||||
*
|
*
|
||||||
* @author 夜雨
|
* @author 夜雨
|
||||||
*/
|
*/
|
||||||
@Target(ElementType.PARAMETER)
|
@Target({ElementType.PARAMETER, ElementType.FIELD})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface Qualifier {
|
public @interface Qualifier {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user