如何在使用Maven的Spring Boot 2 Java应用程序构建中使用Groovy解释(带有spring-aop注释)? [英] How to use groovy interpreted (with spring-aop annotation) within an spring boot 2 java application build with maven?
问题描述
我有一个Spring Boot 2 Java应用程序,想使用解释(而不是编译)的groovy代码注入aop.通过阅读Spring文档,这听起来似乎可行,但是我找不到任何示例. AOP-为脚本豆提供建议:
I have a spring boot 2 java app and would like to use interpreted (not compiled) groovy code to inject aop. From reading the spring documentation this sounds like it is possible, but I could'nt find any examples. AOP - advising scripted beans:
您当然不仅限于为脚本化的bean提供建议……您还可以使用受支持的动态语言自己编写方面,并使用此类bean来建议其他Spring bean.不过,这确实是对动态语言支持的高级使用.
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自身进行注入.
At the end I would like to have a directory where I could add groovy scripts (for business logic) to the application that will inject themself via spring-aop.
我不确定在这种情况下Spring Boot 2会自动执行什么操作,还是我必须手动集成基于org.springframework.scripting的代码?
What I am not sure about is what is spring boot 2 automagically doing in such a case, or do I have to integrate code based on org.springframework.scripting manually?
这是我的小测试项目:
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>
TestConfig.java
TestConfig.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
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
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
GetText.java
package de.test;
import org.springframework.stereotype.Component;
@Component
public class GetText
{
public String getText()
{
return "test1";
}
}
Commandline.java
Commandline.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());
}
}
testAspect.groovy
testAspect.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".
Which results in only "test1" as output instead of the wanted "test1; test2".
Update1:
Update1:
- 添加了TestConfig.java
- 将src/main/groovy/groovy/testAspect.groovy移至src/main/resources/groovy/testAspect.groovy
- 改进了一些内容,但仍然无法正常工作.
Update2:
- 添加了GetText.java
- 修改后的Commandline.java以使用GetText bean
- 更改了PointCut
- 仍然无法正常工作
Update3:
- 添加了applicationContext.xml
- 现在在org.springframework.aop.AopInvocationException中运行:通知方法参数的不匹配[public java.lang.String groovy.TestAspect.doChangeGetText(org.aspectj.lang.ProceedingJoinPoint)抛出java.lang.Throwable];切入点表达式[org.aspectj.weaver.internal.tools.PointcutExpressionImpl@4c4f4365];嵌套异常是java.lang.IllegalArgumentException:对象不是声明类的实例
- 在将testAspect.groovy复制为java类时-切入点将按预期工作,并且将附加; test 2",但作为groovy脚本,上述异常将发生.
- 添加接口IGetText和/或IAspectTest将无济于事
推荐答案
这是一个经典问题,在这里被问过数十遍了:
This is a classic question and was asked dozens of times here:
Spring AOP不会拦截bean内的自调用,而只会拦截其他类对公共Spring bean方法的调用.
Spring AOP does not intercept self-invocation within beans, only calls from other classes to public Spring bean methods. This is also documented in the Spring manual.
这篇关于如何在使用Maven的Spring Boot 2 Java应用程序构建中使用Groovy解释(带有spring-aop注释)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!