简体   繁体   English

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

[英]How to use groovy interpreted (with spring-aop annotation) within an spring boot 2 java application build with maven?

I have a spring boot 2 java app and would like to use interpreted (not compiled) groovy code to inject aop. 我有一个spring boot 2 java app,并希望使用解释(未编译)的groovy代码来注入aop。 From reading the spring documentation this sounds like it is possible, but I could'nt find any examples. 从阅读弹簧文档这听起来有可能,但我找不到任何例子。 AOP - advising scripted beans : AOP - 建议脚本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. 您当然不仅限于为脚本bean提供建议......您还可以使用受支持的动态语言编写方面本身,并使用此类bean来建议其他Spring bean。 This really would be an advanced use of the dynamic language support though. 这确实是动态语言支持的高级用法。

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. 最后,我想有一个目录,我可以将groovy脚本(用于业务逻辑)添加到应用程序,它将通过spring-aop注入自己。

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? 我不确定的是Spring Boot 2在这种情况下自动执行的操作,还是我必须手动集成基于org.springframework.scripting的代码?

So here is my small test project: 所以这是我的小测试项目:

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 的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";
   }
 }

After

mvn clean install

I start it with 我开始吧

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

Which results in only "test1" as output instead of the wanted "test1; test2". 这导致只有“test1”作为输出而不是想要的“test1; test2”。

Update1: UPDATE1:

  • Added TestConfig.java 添加了TestConfig.java
  • Moved src/main/groovy/groovy/testAspect.groovy to src/main/resources/groovy/testAspect.groovy 将src / main / groovy / groovy / testAspect.groovy移至src / main / resources / groovy / testAspect.groovy
  • Improved some things, but still does not work. 改进了一些东西,但仍然无效。

Update2: UPDATE2:

  • Added GetText.java 添加了GetText.java
  • Modified Commandline.java to use GetText bean 修改了Commandline.java以使用GetText bean
  • Changed PointCut 改变了PointCut
  • Still doesn't work 仍然无法正常工作

Update3: UPDATE3:

  • Added applicationContext.xml 添加了applicationContext.xml
  • Now runing in an org.springframework.aop.AopInvocationException: Mismatch on arguments to advice method [public java.lang.String groovy.TestAspect.doChangeGetText(org.aspectj.lang.ProceedingJoinPoint) throws java.lang.Throwable]; 现在在org.springframework.aop.AopInvocationException中运行:对advice方法的参数不匹配[public java.lang.String groovy.TestAspect.doChangeGetText(org.aspectj.lang.ProceedingJoinPoint)throws java.lang.Throwable]; pointcut expression [org.aspectj.weaver.internal.tools.PointcutExpressionImpl@4c4f4365]; 切入点表达式[org.aspectj.weaver.internal.tools.PointcutExpressionImpl@4c4f4365]; nested exception is java.lang.IllegalArgumentException: object is not an instance of declaring class 嵌套异常是java.lang.IllegalArgumentException:object不是声明类的实例
  • When copying the testAspect.groovy over as java class - then the pointcut works as expected and ";test 2" will be appended, but as groovy script the above exception will haben. 当将testAspect.groovy作为java类复制时 - 然后切入点按预期工作,并且将附加“; test 2”,但作为groovy脚本,上述异常将是haben。
  • Adding an interface IGetText and/or IAspectTest will not help 添加接口IGetText和/或IAspectTest将无济于事

This is a classic question and was asked dozens of times here: 这是一个经典问题,在这里被问过几十次:

Spring AOP does not intercept self-invocation within beans, only calls from other classes to public Spring bean methods. Spring AOP不拦截bean内的自调用,只调用从其他类到公共Spring bean方法的调用。 This is also documented in the Spring manual . 这也在Spring手册中有记录

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM