Spring AOP не работает при использовании в качестве скомпилированного фляги в другом проекте - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть работающий AOP (при использовании внутри проекта, в котором он написан), но когда я собираю этот проект (maven install), использую этот JAR в другом проекте и пытаюсь использовать аннотацию @TimedLog, ничего не происходит , Я пытаюсь проникнуть в нее, но она туда не доходит.

Это выглядит так:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TimedLog {
    boolean shouldAttachMethodArgs() default false;
    boolean shouldAttachReturnValue() default false;
    String message() default "";
}

Это фактический аспект:

@Aspect
@Configuration
@Slf4j
public class MethodExecutionAspect {

    @Pointcut("@annotation(timedLogVar)")
    public void annotationPointCutDefinition(TimedLog timedLogVar) {}

    @Pointcut("execution(* *(..))")
    public void atExecution() {}

    @Around(value = "annotationPointCutDefinition(timedLogVar) && atExecution()", argNames = "joinPoint,timedLogVar")
    public Object around(ProceedingJoinPoint joinPoint, TimedLog timedLogVar) throws Throwable {
        Stopwatch stopwatch = Stopwatch.createStarted();
        Object returnValue = joinPoint.proceed();
        stopwatch.stop();

        log.info(String.format("test message %s", stopwatch.elapsed(TimeUnit.MILLISECONDS)));

        return returnValue;
    }
}

Реализация этого будет:

@TimedLog
void testDefaultValues() throws InterruptedException {
    int sleepTimeInMillis = 200;
    log.info("Resting for {} millis", value("sleepTimeInMillis", sleepTimeInMillis));
    Thread.sleep(sleepTimeInMillis);
}

pom.xml

<!-- AOP -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.0.2.RELEASE</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.13</version>
    <scope>compile</scope>
</dependency>

Из того, что вы видите здесь, это AOP, который украшает метод и регистрирует его время выполнения.

Я уже некоторое время борюсь с этим и буду очень признателен за вашу помощь.

Спасибо

EDIT: В соответствии с запросом, полный pom.xml проекта, который должен использовать этот AOP (он живет foo.bar.utils: utils-common)

<?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">
    <parent>
        <artifactId>backend</artifactId>
        <groupId>foo.bar.backend</groupId>
        <version>2.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>backend-logic</artifactId>
    <repositories>
        <repository>
            <id>maven-s3-release-repo</id>
            <name>S3 Release Repository</name>
            <url>s3://repository.foobar.com/releases</url>
        </repository>
        <repository>
            <id>maven-s3-snapshot-repo</id>
            <name>S3 Snapshot Repository</name>
            <url>s3://repository.foobar.com/snapshots</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>foo.bar.backend</groupId>
            <artifactId>backend-contract</artifactId>
            <version>2.0.0-SNAPSHOT</version>
        </dependency>

        <!-- Spring boot actuator to expose metrics endpoint -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- Micormeter core dependecy  -->
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-core</artifactId>
        </dependency>
        <!-- Micrometer Prometheus registry  -->
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
        </dependency>

        <!-- Common -->
        <dependency>
            <groupId>foo.bar.utils</groupId>
            <artifactId>utils-common</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>

        <!-- Auth -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
            <version>2.0.0.M1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <!-- Utils -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-joda</artifactId>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>
    <build>
        <extensions>
            <extension>
                <groupId>org.springframework.build</groupId>
                <artifactId>aws-maven</artifactId>
                <version>5.0.0.RELEASE</version>
            </extension>
        </extensions>
    </build>

</project>

EDIT2: Реализация, которая не работает (в другом проекте, который должен использовать AOP)

@Slf4j
@Configuration
@EnableAspectJAutoProxy
public class TestingSomething {

    @TimedLog(message = "test something")
    public void testingSomething() {
        log.info("ololol");
    }

}

И тест, тестирующий его:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SomeSpringConfiguration.class,
        properties = {"server.port=0", "enable.security=true"})
@WebAppConfiguration
public class testingSomethingTest {
    @Autowired
    TestingSomething testingSomething;

    @Test
    public void testingLol() {
        testingSomething.testingSomething();
    }
}

1 Ответ

0 голосов
/ 12 сентября 2018

Чтобы аспекты работали, их нужно включить. Для включения вам необходимо настроить их через xml или через аннотацию:

@Configuration
@EnableAspectJAutoProxy

Через xml:

<beans …>
      <!– Enable AspectJ auto-wiring –>
      <aop:aspectj-autoproxy />
</beans>

Когда вы включаете свой jar в другое приложение, это другое приложение имеет свою собственную конфигурацию и контекст. Даже если вы включили автоматическую разводку аспектов для своего исходного контекста, вам все равно нужно сделать то же самое для вашего нового приложения одним из двух способов, указанных выше.

Если вы используете аннотацию, убедитесь, что она находится в области сканирования компонента и действительно включена в ваш контекст.

UPDATE: выполните @Import (MethodExecutionAspect.class) в своем тестировании SomethingTest, чтобы убедиться, что оно сканируется компонентом.

...