gpt4 book ai didi

java - 如何在使用 maven 构建的 spring boot 2 java 应用程序中使用 groovy 解释(带有 spring-aop 注释)?

转载 作者:搜寻专家 更新时间:2023-10-31 20:16:56 25 4
gpt4 key购买 nike

我有一个 spring boot 2 java 应用程序,想使用解释的(未编译的)groovy 代码来注入(inject) aop。通过阅读 spring 文档,这听起来像是可能的,但我找不到任何示例。 AOP - advising scripted beans :

You are of course not just limited to advising scripted beans…​ you can also write aspects themselves in a supported dynamic language and use such beans to advise other Spring beans. This really would be an advanced use of the dynamic language support though.

最后我想要一个目录,我可以在其中将 groovy 脚本(用于业务逻辑)添加到将通过 spring-aop 注入(inject)自身的应用程序。

我不确定的是 spring boot 2 在这种情况下会自动执行什么操作,还是我必须手动集成基于 org.springframework.scripting 的代码?

所以这是我的小测试项目:

project
|-pom.xml
|src/main/java/de/test
|-Commandline.java
|-MytestApplication.java
|-TestConfig.java
|-GetText.java
|src/main/resources/groovy
|-testAspect.groovy
|src/main/resources
|-application.properties (empty at the moment)
|-applicationContext.xml

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>de.test</groupId>
<artifactId>mytest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>mytest</name>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/>
</parent>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
</dependency>
</dependencies>

</project>

测试配置.java

package de.test;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan({"de.test", "groovy"})
@ImportResource({"classpath*:applicationContext.xml"})
public class TestConfig
{
}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

<lang:groovy id="testAspect" refresh-check-delay="30000" script-source="classpath:groovy/TestAspect.groovy"/>

</beans>

MytestApplication.java

package de.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan({"de.test", "groovy"})
@SpringBootApplication
public class SpringboottestApplication
{
public static void main(final String[] args)
{
SpringApplication.run(SpringboottestApplication.class, args);
}
}

GetText.java

package de.test;

import org.springframework.stereotype.Component;

@Component
public class GetText
{
public String getText()
{
return "test1";
}

}

命令行.java

package de.test;

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class Commandline implements CommandLineRunner
{
@Autowired
GetText textbean;

public Commandline()
{
super();
}

@Override
public void run(final String... args) throws Exception
{
System.out.println((this.textbean.getText());
}
}

测试方面.groovy

package groovy

import org.springframework.stereotype.Component

import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect

@Aspect
@Component
class TestAspect
{
@Around("execution(String de.test.GetText.getText())")
public String doChangeGetText(ProceedingJoinPoint pjp) throws Throwable
{
String retVal = (String)pjp.proceed();
return retVal + "; test2";
}
}

之后

mvn clean install

我从这里开始

java -jar target/mytest-0.0.1-SNAPSHOT.jar

这只会导致“test1”作为输出,而不是想要的“test1;test2”。

更新 1:

  • 添加了 TestConfig.java
  • 将 src/main/groovy/groovy/testAspect.groovy 移动到 src/main/resources/groovy/testAspect.groovy
  • 改进了一些东西,但仍然不起作用。

更新2:

  • 添加了 GetText.java
  • 修改 Commandline.java 以使用 GetText bean
  • 更改切入点
  • 还是不行

更新3:

  • 添加了applicationContext.xml
  • 现在在 org.springframework.aop.AopInvocationException 中运行:建议方法的参数不匹配切入点表达式 [org.aspectj.weaver.internal.tools.PointcutExpressionImpl@4c4f4365];嵌套异常是 java.lang.IllegalArgumentException: object is not an instance of declaring class
  • 当将 testAspect.groovy 复制为 java 类时 - 然后切入点按预期工作并且将附加“;test 2”,但作为 groovy 脚本,上述异常将会发生。
  • 添加接口(interface) IGetText 和/或 IAspectTest 无济于事

最佳答案

这是一个经典问题,在这里被问了几十次:

Spring AOP 不会拦截bean 内部的自调用,只会拦截其他类对公共(public)Spring bean 方法的调用。这也记录在 Spring manual 中。 .

关于java - 如何在使用 maven 构建的 spring boot 2 java 应用程序中使用 groovy 解释(带有 spring-aop 注释)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52091228/

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