gpt4 book ai didi

java - AspectJ 和 CDI

转载 作者:塔克拉玛干 更新时间:2023-11-01 23:08:09 24 4
gpt4 key购买 nike

我正在尝试找出一种将 bean 注入(inject)方面的方法。

我是说

public class Greeter {
public String greet(String name) {....}
}

...

public aspect GreeterAspect {
@Inject
private Greeter greeter

...
}

使用 Arquillian + Wildfly 8.2.1(托管和远程)将其作为 JUnit 测试执行,我得到以下几行日志:

WELD-000119: Not generating any bean definitions from x.y.z.Greeter because of underlying class loading error: Type org.aspectj.runtime.internal.AroundClosure from [Module "deployment.test.war:main" from Service Module Loader] not found.
WELD-000119: Not generating any bean definitions from x.y.z.GreeterAspect because of underlying class loading error: Type org.aspectj.lang.NoAspectBoundException from [Module "deployment.test.war:main" from Service Module Loader] not found.

在我收到错误后不久

WELD-001474: Class x.y.z.Greeter is on the classpath, but was ignored because a class it references was not found: org.aspectj.runtime.internal.AroundClosure from [Module "deployment.test.war:main" from Service Module Loader].

如果我做对了,它会提示 aspectjrt.jar 不在类路径中,尽管我已经检查并在依赖项中得到它(使用 Maven 构建)。在 provided 范围内,尝试切换到 compile 但没有任何改变。

谁能帮我解决这个问题?

编辑:解决了最初的问题,现在是 NullPointerException

按照 simas_ch 的建议,通过将 aspectjrt.jar 添加到 Arquillian 部署来解决最初的问题。

虽然,在执行时,我收到一个 NullPointerException

public class Greeter {
public String greet(String name) {....}
}

...

public aspect GreeterAspect {
@Inject
private Greeter greeter;

private pointcut pc() : execution(* x.y.z.SomeClass.someMethod(..));

String around() : pc() {
log.debug("Aspect is about to say something...");
String result = greeter.greet("Stefano");
log.debug("Aspect said: " + result);
return proceed();
}
}

我可以看到第一行日志(Aspect is about to say something...)然后我得到了 NullPointerException,显然是 Greeter bean 还没有被注入(inject)。

我做错了什么?或者是否有可能将 bean 注入(inject)方面?

最佳答案

感谢社区的帮助,我设法找到了解决这两个问题的方法。在这里留下足迹。

第一部分 - 部署中的 aspectjrt.jar

首先,添加Shrinkwrap对我的依赖:

<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-api-maven</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-impl-maven</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-impl-maven-archive</artifactId>
<scope>test</scope>
</dependency>

<version>不需要:Arquillian 的 BOM - 已经包括在内 - 会解决这个问题。

然后添加aspectj到部署类路径:

@RunWith(Arquillian.class)
public class ArquillianTest {
private static final String[] DEPENDENCIES = {
"org.aspectj:aspectjrt:1.8.7"
};

@Deployment
public static JavaArchive createEnvironement() {
JavaArchive lib = ShrinkWrap.create(JavaArchive.class, "libs.jar");
for (String dependency : DEPENDENCIES) {
lib.merge(Maven.resolver().resolve(dependency).withTransitivity().asSingle(JavaArchive.class));
}

JavaArchive jar = ShrinkWrap.create(JavaArchive.class)
// create you deployment here
.as(JavaArchive.class);

JavaArchive toBeDeployed = jar.merge(lib);

return toBeDeployed;
}

// other stuff, like tests

}

第二部分:将 bean 注入(inject)切面

经过进一步询问,我认为 simas_ch 说 CDI 不将 bean 注入(inject)方面是正确的。

想出了一个解决方法:添加一个 @Inject通过切面将成员编辑到 bean 中。

public interface Advised {
String buildGreeting(String name);
}

public class AdvisedImpl implements Advised {
String buildGreeting(String name) {
return "ADVISED";
}
}

public class Greeter {
public String greet(String name) {
return "Hello, " + name + ".";
}
}

...

public aspect GreeterAspect {
@Inject
private Greeter Advised.greeter; // adding the member to the interface / class. No need for getters / setters

private pointcut pc() : execution(* x.y.z.Advised.buildGreeting(String));

String around(Advised adv, String name) : pc() && target(adv) && args(name) {
log.debug("Aspect is about to say something...");
String result = proceed(adv, name) + " - " + adv.greeter.greet(name);
log.debug("Aspect said: '" + result + "'");
return result;
}
}

给定测试

@Test
public void test() {
assertThat(advised, not(is(nullValue())));
assertThat(advised.buildGreeting("Stefano"), equalToIgnoringCase("advised - hello, stefano."));
}

它成功了。

关于java - AspectJ 和 CDI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36038652/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com