一般问题
我有两个项目A和B;B依赖于A。我想使用注释处理器在B中生成一些代码,基于A中对象的注释。当我使用正确的处理器实现进行编译时,只有来自B的标记对象被选中。
我理解默认情况下必须禁用对其他JAR的扫描,因为通常不希望扫描所有依赖项的注释。我也明白由于编译器魔法(我对此知之甚少)可能无法做到我想做的事情,但我希望不能这样。
具体案例
我的项目名为DB和WEB。 WEB显然依赖于DB以获取其JPA访问权限;这在Maven中进行了配置。由于一些架构选择,DB必须保持单独的JAR。除了WEB使用Spring MVC外,DB并不使用Spring,但会使用一些注解,这些注解被WEB所消耗。
我正在尝试使用注释处理器为所有JPA实体生成CrudRepository
接口。 @Repository
对象应该放在WEB项目中的repo
包中,以便可以在WEB应用程序的任何位置使用@Autowired
。 我要扫描的注释是@javax.persistence.Entity
,但我也尝试过自定义注释,结果相同。
@SupportedAnnotationTypes("javax.persistence.Entity")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class RepositoryFactory extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (Element e : roundEnv.getElementsAnnotatedWith(Entity.class)) {
if (e.getKind() != ElementKind.CLASS) {
continue;
}
// TODO: implement logic to skip manually implemented Repos
try {
String name = e.getSimpleName().toString();
TypeElement clazz = (TypeElement) e;
JavaFileObject f = processingEnv.getFiler().
createSourceFile("blagae.web.repo." + name + "Repo");
try (Writer w = f.openWriter()) {
PrintWriter pw = new PrintWriter(w);
pw.println("package blagae.web.repo;");
pw.println("import org.springframework.data.repository.CrudRepository;");
pw.printf("import %s;\n", clazz.toString());
pw.println("import org.springframework.stereotype.Repository;");
pw.println("@Repository");
pw.printf("public interface %sRepo extends CrudRepository<%s, Long> {}\n", name, name);
pw.flush();
}
} catch (IOException ex) {
Logger.getLogger(RepositoryFactory.class.getName()).log(Level.SEVERE, null, ex);
}
}
return false;
}
}
理想情况下,我希望有人告诉我一种注释方式,它应该像这样简单:
@ComponentScan(basePackages = "blagae.db.*")
当然,我并不指望这样做,因为它可能已经在某个地方有文档记录了。作为解决办法,我可以将Spring依赖项添加到db中,并在那里生成类,但是它们只在Spring MVC应用程序中起作用。我也担心让这个工作起来需要多少配置。
更新
一些额外的信息:我正在使用maven-processor-plugin,在WEB项目中定义的类中,我已经验证它的工作情况良好。然而,我特别想访问在依赖项目DB中注释过的类。我已经查看了方法AbstractProcessor::getSupportedOptions
,但我不清楚在那里能做什么。
Maven配置:
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>2.2.4</version>
<configuration>
<processors>
<processor>blagae.utils.RepositoryFactory</processor>
</processors>
</configuration>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
</execution>
</executions>
</plugin>
建议
我又想到了一个随机的想法,就是在 WEB 的 DB 项目中运行一个 JavaCompiler
进程,但是我该如何注入我的 Processor
呢?