视频
建议
同时使用 IDE 插件增强(Idea 或 Eclipse)和构建时增强。
对于 IntelliJ IDEA 和 Eclipse 用户,我的建议是除了构建时增强(maven 插件)或代理外,还要使用 IDE 插件。
也就是说,IDE 插件在开发期间很好用,可以在 IDE 编译类时增强 Bean。使用 IDE 插件可以减少开发和单元测试期间的增强麻烦。对于生产,您可以在构建时增强(例如 maven)或运行时增强(例如 javaagent)之间进行选择。
概述
术语“增强”涵盖了用于修改实体 Bean 的所有方式(javaagent、ant、maven、IDE 插件等)。用于描述增强的其他术语包括“编织”、“转换”和“字节码操作”。
加载时编织用于指在“加载时”通常通过 javaagent 发生类操作,而类操作在“构建时”通常通过 Maven、Ant 或 IDE 插件发生。
从原始意义上讲,类是一个 byte[],增强是在类由其 ClassLoader 定义之前操作这些字节。
使用多个增强器
Ebean 增强会意识到增强何时已经发生。通过这种方式,通常且预期可以同时使用多种形式的增强,例如同时使用 IDE 插件和 maven 插件来执行增强。
Maven 增强
Maven 插件在 maven 编译过程中执行增强。这可以描述为“构建时增强”。
Maven 增强模块
Ebean 提供了一个 maven 模块,它同时引入了实体 Bean 的增强器和查询 Bean 的增强。这比以传统(非模块)方式定义插件更简单、更简洁、更简洁,现在是首选方法。
ebean 增强模块为以下内容带来插件配置
- 实体 bean 和 @Transactional 增强(适用于主模块和测试)
- 查询 bean 增强(适用于主模块和测试)
- ebean-codegen 插件,用于生成查找器等
ebean 增强图块
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.22</version>
<extensions>true</extensions>
<configuration>
<tiles>
<!-- other tiles ... -->
<tile>io.ebean.tile:enhancement:13.25.0</tile>
</tiles>
</configuration>
</plugin>
使用 mvn help:effective-pom
查看图块引入的插件。
Maven 插件
如果您不想使用 maven 图块,则可以以“普通”方式指定 maven 增强插件。请注意,与图块不同,这不会引入 查询 bean 增强。
<plugin>
<groupId>io.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
<version>${version}</version>
<executions>
<execution>
<id>main</id>
<phase>process-classes</phase>
<configuration>
<transformArgs>debug=1</transformArgs>
</configuration>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
</plugin>
代理
您可以根据以下示例在命令行上使用 javaagent
参数。这通常被称为“运行时增强”或“加载时增强”。
请注意,从 ebean-agent 4.7.1 版本开始,预计该代理将在不指定要增强的包的情况下良好运行。也就是说,该代理非常擅长忽略不感兴趣的类(JDK、groovy、scala、kotlin、jdbc 驱动程序以及来自 apache、google、testing 等的许多常见库)。
java -javaagent:ebean-agent-${version}.jar MyApplication
java -javaagent:ebean-agent-${version}.jar=debug=3 MyApplication
可以从 maven 下载 ebean-agent jar。当前版本为
<dependency>
<groupId>${groupid}</groupId>
<artifactId>${artifactid}</artifactId>
<version>${version_str}</version>
</dependency>
<dependency org="${groupid}" name="${artifactid}" rev="${version_str}"/>
@Grapes(
@Grab(group='${groupid}', module='${artifactid}', version='${version_str}')
)
'${groupid}:${artifactid}:${version_str}'
'${groupid}:${artifactid}:${version_str}'
libraryDependencies += "${groupid}" % "${artifactid}" % "${version_str}"
[${groupid}/${artifactid} "${version_str}"]
代理加载器
代理加载器可用于以编程方式将 javaagent 加载到正在运行的 JVM 上。但是,这偶尔不会增强 bean,因为实体 bean 类在 JVM 上加载代理之前已加载,因此不建议采用此方法。
请注意,此方法用于 Ebean 本身的测试代码中,如果您使用此方法,则需要确保在加载任何实体 bean 或事务 bean 的类之前加载代理。
<dependency>
<groupId>${groupid}</groupId>
<artifactId>${artifactid}</artifactId>
<version>${version_str}</version>
</dependency>
<dependency org="${groupid}" name="${artifactid}" rev="${version_str}"/>
@Grapes(
@Grab(group='${groupid}', module='${artifactid}', version='${version_str}')
)
'${groupid}:${artifactid}:${version_str}'
'${groupid}:${artifactid}:${version_str}'
libraryDependencies += "${groupid}" % "${artifactid}" % "${version_str}"
[${groupid}/${artifactid} "${version_str}"]
以下代码以编程方式将增强器代理加载到正在运行的 JVM 上。
import org.avaje.agentloader;
...
public void someApplicationBootupMethod() {
// Load the agent into the running JVM process
if (!AgentLoader.loadAgentFromClasspath("ebean-agent","debug=1;packages=org.example.model")) {
logger.info("ebean-agent not found in classpath - not dynamically loaded");
}
}
Ant 增强
修改 ant build.xml 文件为
- 定义 AntEnhanceTask。
- 创建一个使用 AntEnhanceTask 增强实体类的目标。
<taskdef
name="ebeanEnhance"
classname="io.ebean.enhance.ant.AntEnhanceTask"
classpath="your_path_to/ebean-x.x.x.jar"/>
<target name="ormEnhance" depends="clean,compile">
<!--
classSource: This is the directory that contains your class files. That is, the directory where your IDE will compile your java class files to, or the directory where a previous ant task will compile your java class files to.
packages: a comma delimited list of packages that contain entity classes. All the classes in these packages are searched for entity classes to be enhanced. transformArgs: This contains a debug level (0 - 10) .
-->
<ebeanEnhance
classSource="your_classes_directory"
packages="app.domain.*"
transformArgs="debug=1"/>
</target>