用于远程JAR的Java注释处理器 一般问题
我有两个项目A和B;B依赖于a。我想基于a中对象的注释,在B中使用注释处理器生成一些代码。当我使用正确的处理器实现运行编译时,只从B中拾取注释对象 我理解默认情况下必须禁用扫描其他JAR,因为您通常不希望对所有依赖项进行注释扫描。我也明白,由于编译器的魔力,我想做的事情可能是不可能的——我对编译器的魔力知之甚少——但我希望不是这样 具体案例 我的项目叫做DB和WEB。WEB显然依赖DB进行JPA访问;这是在Maven中配置的。由于有许多架构选择,DB必须保持为一个单独的JAR。DB不使用Spring,除了WEB使用的一些注释;WEB使用SpringMVC 我正试图用注释处理器为我的所有JPA实体生成用于远程JAR的Java注释处理器 一般问题,java,maven,jpa,annotation-processing,javacompiler,Java,Maven,Jpa,Annotation Processing,Javacompiler,我有两个项目A和B;B依赖于a。我想基于a中对象的注释,在B中使用注释处理器生成一些代码。当我使用正确的处理器实现运行编译时,只从B中拾取注释对象 我理解默认情况下必须禁用扫描其他JAR,因为您通常不希望对所有依赖项进行注释扫描。我也明白,由于编译器的魔力,我想做的事情可能是不可能的——我对编译器的魔力知之甚少——但我希望不是这样 具体案例 我的项目叫做DB和WEB。WEB显然依赖DB进行JPA访问;这是在Maven中配置的。由于有许多架构选择,DB必须保持为一个单独的JAR。DB不使用Spri
crudepository
接口。@Repository
对象应该放在WEB项目中的repo
包中,因此它们可以与@Autowired
一起在WEB应用程序中的任何位置使用。我正在执行扫描的注释是@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;
}
}
但当然,我不指望它,因为它可能会被记录在某个地方。作为一种解决方法,我可以将Spring依赖项添加到db中并在那里生成类,但它们只在SpringMVC应用程序中起作用。我还对可能需要的配置持谨慎态度
更新
一些额外的信息:我正在使用maven处理器插件,我已经验证了它在WEB项目中对于在那里定义的类工作得很好。但是,我特别希望在依赖项项目DB中注释access类。我已经研究了方法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>
org.bsc.maven
maven处理器插件
2.2.4
blagae.utils.RepositoryFactory
过程
过程
生成源
暗示
我的另一个随机想法是为WEB中的DB项目运行
JavaCompiler
进程,但是如何注入处理器呢?就我个人而言,我会在单独的maven模块中提取注释处理器,并从WEB模块向其添加依赖项
然而,对于成功触发注释处理器来说,这并不重要
为了让注释处理器工作,您必须提供两件事:
- 扩展该类的类
- 一个特殊文件,嵌套在项目的
META-INF/services
中
既然您提到目前没有生成任何类,我就假设您丢失了元文件。因此,打开WEB项目并导航到src/main/resources
文件夹。在中,您必须创建一个META-INF
文件夹,其中包含嵌套的services
文件夹。然后,在services
中创建一个名为javax.annotation.processing.Processor的文件。文件内容应列出注释处理器的完全限定类名。如果有多个注释处理器,则完全限定的类名应位于单独的行中。但既然你只有一个,你就会有这样的东西:
com.yourdomain.processor.RepositoryFactory
<build>
<resources>
...
<resource>
<directory>${project.build.directory}/generated-resources</directory>
</resource>
</resources>
</build>
请注意,您必须使用注释处理器的实际完全合格类名更改此行
最后,您应该得到类似的结构:
这个元文件很重要,因为否则编译器不会知道用户定义的注释处理器。有了它,它将使用所有注册的处理器
之后,当您执行mvn清理安装时
将清理并构建所有模块。但是,由于编译器现在会知道您的注释处理器,因此会触发它。所有生成的源(默认情况下)将位于目标/生成的源
文件夹中。此外,它们都将位于您在注释过程中配置的包下,即blagae.web.repo
为了在代码中使用生成的源,必须将targetr/generated sources
添加到项目类路径中。如果您不想依赖IDE来实现这一点,可以通过向类路径添加目标/生成源来扩展maven
。比如:
com.yourdomain.processor.RepositoryFactory
<build>
<resources>
...
<resource>
<directory>${project.build.directory}/generated-resources</directory>
</resource>
</resources>
</build>
...
${project.build.directory}/生成的资源
注释处理器在项目的编译阶段工作(在您的案例中是WEB),编译器编译此项目。当前项目的依赖项已经编译,编译器(以及您的注释处理器)不会接触(或无法访问)第三方库(DB)
您可以尝试将注释处理器提取到单独的project/jar中,并在WEB和DB项目中使用它。在这种情况下,注释处理器将在具体项目的编译阶段创建crudepository
。DB project中生成的所有类都将在WEB上可用。在项目A中包括META-INF/beans.xml文件,
其中将包含以下内容:
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee <a href="http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd">http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"</a>
version="1.1" bean-discovery-mode="all">
</beans>
我不明白这个问题-注释处理器不工作或…?:)我希望在WEB项目上运行注释处理器时从DB项目(=jar)中提取注释。到目前为止,这种情况还没有发生。我可以提出一个解决方案。等一会儿,我好把它写下来