带有现代 spring-boot + gradle 的简单 @Configurable

Simple @Configurable with modern spring-boot + gradle

我的目标是获得基本的 aspectj+spring aop 设置,这样我就可以在一个 class 上使用 @Configurable。另一个限制是它需要使用加载时编织,因为 Lombok 不能与 CTW 一起使用。

好消息:我成功了!

坏消息:控制台充斥着 [Xlint:cantFindType] 错误。请参阅下面的结果部分。

环境

我有一个用 @Configurable 注释的 class。它是由 Jackson 使用并实例化的 class,因此需要 AOP。这不是很有趣,所以我不会在这里展示。它只是一个普通的 class,带有 Configurable 的单个注解,里面有一个 @Autowired bean。

SpringBoot应用程序

我的应用程序 class 具有通常的注释:

@SpringBootApplication
@EnableSpringConfigured
@EnableLoadTimeWeaving
public class MyApplication {

build.gradle

我的 build.gradle 有所有常见的嫌疑人。示例:

configurations {
    springinstrument
}

dependencies {
    compile('org.projectlombok:lombok')

    compile('org.springframework.boot:spring-boot-starter-aop')
    compile("org.springframework.boot:spring-boot-starter-data-rest")
    compile('org.springframework.data:spring-data-rest-hal-browser')
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-security')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-devtools')
    compile('org.springframework.plugin:spring-plugin:1.2.0.RELEASE')
..snip..
    runtime('org.springframework:spring-instrument:4.+')
    springinstrument "org.springframework:spring-instrument:4.+"
    runtime configurations.springinstrument.dependencies
}

test.doFirst {
    jvmArgs "-javaagent:${configurations.springinstrument.asPath}"
}

jvm 参数

我正在 运行使用以下参数进行 JUnit 测试(通过 Intellij 的 运行 配置)

-ea
-javaagent:/Users/me/.gradle/caches/modules-2/files-2.1/org.springframework/spring-instrument/4.3.3.RELEASE/5db399fa5546172b9c107817b4abaae6b379bb8c/spring-instrument-4.3.3.RELEASE.jar

aop.xml

我有一个 src/main/resources/META-INF/aop.xml 包含:

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
        <weaver options="-Xreweavable -showWeaveInfo">
        <!-- only weave classes with @Configurable interface -->
        <include within="@org.springframework.beans.factory.annotation.Configurable */>
    </weaver>
</aspectj>

但是,我怀疑这个文件没有被提取。不管我在文件中放了什么,结果总是一样的。即使我随机输入无效 XML.

测试

junit 测试是一个简单的 Jackson 序列化-反序列化测试,使用 @Configurable 注释 class。

测试class有注释:

@SpringBootTest
@RunWith(SpringRunner.class)

结果

当 运行通过 Intellij 进行 junit 测试时 -> 它有效,但是..

LTW 实际工作,当 运行 通过 Intellij 和上面的 jvm args 时,我的测试通过了。

然而,应用程序的启动时间明显更长并且日志中充斥着Xlint:cantFindType个错误

示例:

2016-11-07 19:28:21.944  INFO 45213 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
[AppClassLoader@18b4aac2] error can't determine implemented interfaces of missing type org.springframework.security.ldap.authentication.LdapAuthenticationProvider
when weaving type org.springframework.security.config.annotation.authentication.configurers.ldap.LdapAuthenticationProviderConfigurer
when weaving classes 
when weaving 
 [Xlint:cantFindType]
[AppClassLoader@18b4aac2] error can't determine implemented interfaces of missing type io.undertow.server.handlers.accesslog.AccessLogHandler
when weaving type org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory
when weaving classes 
when weaving 
 [Xlint:cantFindType]
[AppClassLoader@18b4aac2] error can't determine implemented interfaces of missing type io.undertow.server.handlers.accesslog.AccessLogHandler
when weaving type org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory
when weaving classes 
when weaving 
 [Xlint:cantFindType]
[AppClassLoader@18b4aac2] error can't determine implemented interfaces of missing type io.undertow.server.handlers.accesslog.AccessLogHandler
when weaving type org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory
when weaving classes 
when weaving 
 [Xlint:cantFindType]
.. many more.. all in the org.springframework.boot package

当 运行通过 gradle 命令行进行测试时 -> 工作,有点。

当我 运行 使用 gradle test --tests *MyTestClass 进行测试时,测试失败,因为 NullPointerException on..猜猜是什么,我期待的 @Autowired bean自动注入。

我用 gradle 测试配置得到了它,huzzah!我已经更新了上面的配置。但是..它遇到了与 运行 在我的 IDE 中一样的问题:the Xlint:cantFindType


所以问题:

  1. gradle 配置错误,因此 运行 通过 gradle 安装应用程序失败。如何修复 gradle 配置?

  2. Xlint:cantFindType 错误。 aop.xml 没有被拾取吗? 如何解决?

我还没有找到一个使用 aop.xml

的简单 spring-boot+gradle+ @Configurable 示例

问题我解决了,比较尴尬

  1. 这是因为 aop.xml 没有被拾取。
  2. 未检测到该文件,因为它位于 class 路径中名为 META_INF/ 的目录中,而不是 META-INF/。这是一个非常重要的区别。

无论如何,我已经用最小配置更新了问题,以便 @Configurable 使用现代 spring-boot 和 gradle 设置,加载时间编织以支持 Lombok .希望它对某人有用。