假设以下代码:
public class Main {
public static final List<Object> configuration = new ArrayList<>();
public static void main(String[] args) {
System.out.println(configuration);
}
}
我现在希望能够提供“自配置”类。这意味着,他们应该能够简单地提供类似静态块的东西,它会像这样自动调用:
public class Custom {
static {
Main.configuration.add(Custom.class);
}
}
如果执行此代码,则配置列表为空(因为静态块的执行方式)。该类是 "reachable" ,但不是 "loaded"。您可以在 System.out 之前将以下内容添加到 Main 类
Class.forName("Custom");
并且该列表现在将包含自定义类对象(由于该类尚未初始化,此调用将对其进行初始化)。但是因为控件应该是反向的(自定义应该知道 Main 而不是相反),这不是一种可用的方法。绝不能直接从 Main 或与 Main 关联的任何类调用 Custom。
但可能的情况如下:您可以向类添加注释并使用所述注释收集所有类,使用类图框架之类的东西并调用Class.forName它们中的每一个。
TL; 博士
有没有办法自动调用静态块,而无需分析所有类,也不需要知道具体的“自配置”类?Perfect 将是一种方法,即在启动应用程序时,自动初始化一个类(如果它们用某个注解进行注解)。我考虑过自定义类加载器,但据我所知,它们很懒惰,因此不适用于这种方法。
这样做的背景是,我想将它合并到一个注释处理器中,它创建“自配置代码”。
示例(警告:设计谈话和深度)
为了让这不那么抽象,请想象以下内容:
你开发一个框架。我们称它为 Foo。Foo 有类 GlobalRepository 和 Repository。GlobalRepository 遵循单例设计模式(仅限静态方法)。Repository 和 GlobalRepository 都有一个方法“void add(Object)”和“T get(Class)”。如果您在 Repository 上调用 get 并且找不到 Class,它会调用 GlobalRepository.get(Class)。
为方便起见,您希望提供一个名为@Add 的注解。这个注解可以放在类型声明(又名类)上。注释处理器创建一些配置,这些配置会自动将所有带注释的类添加到 GlobalRepository 并因此减少样板代码。它应该只(在所有情况下)发生一次。因此,生成的代码有一个静态初始化程序,其中填充了 GlobalRepository,就像您对本地存储库所做的一样。因为您的配置的名称设计得尽可能独特,并且出于某种原因甚至包含创建日期(这有点武断,但请记住),所以它们几乎不可能被猜到。
因此,您还向这些配置添加了一个注释,称为@AutoLoad。您需要使用开发人员调用 GlobalRepository.load(),然后分析所有类并初始化所有带有此注解的类,从而调用它们各自的静态块。
这是一种不太可扩展的方法。应用程序越大,搜索范围越大,时间越长等等。更好的方法是,在启动应用程序时,所有类都会自动初始化。就像通过 ClassLoader 一样。像这样的东西就是我正在寻找的。
弑天下
相关分类