0

I am trying to create an aspect class that with a method of type after or before, finds a target class annotation and prints a text when it is instantiated but it does not work.

Annotation

package com.example.demo

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class AutoGenerateCode()

Aspect

package com.example.demo

import org.aspectj.lang.JoinPoint
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.springframework.stereotype.Component

@Aspect
@Component
class AutoGenerateCodeAspect {

    @Before("@annotation(AutoGenerateCode)")
    fun before(joinPoint: JoinPoint) {
        println("\n\nBEFORE\n\n")
    }
}

Dto class

package com.example.demo

@AutoGenerateCode
class FakeDto {
    val id = ""
}

Main

package com.example.demo

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.EnableAspectJAutoProxy

@SpringBootApplication(scanBasePackages = ["com.example"])
@EnableAspectJAutoProxy
class DemoApplication

fun main(args: Array<String>) {
    runApplication<DemoApplication>(*args)
    val fakeDto = FakeDto()
    println(fakeDto)
}

This prints the object of the FakeDto class, but not the message "BEFORE"

Versions:

  • JAVA: 11
  • SpringBoot: 2.4.1
  • Kotlin: 1.4.21

Help, please

  • This is a typical example of the [XY problem](https://meta.stackexchange.com/a/66378/309898), only explaining **how** (intercept instance creation) you want to achieve your goal, instead of simply explaining which problem you wish to solve. This way, you lose the chance of getting answers suggesting alternatives to your own idea, which would also solve the actual problem. When you have intercepted instance creation, what are you going to do with the information, other than log it? – kriegaex Jul 31 '22 at 09:50
  • Thank you very much, I will review the documentation in the comment below, but I will still explain what I want to do: I need to create a library, with a class annotation, so that every time an object of the annotated class is instantiated, it allows me to set a string code to one of its attributes. – Kevin Giraldo Aug 01 '22 at 13:04

1 Answers1

1

There are two reasons why it does not work:

  • FakeDto - is not managed by Spring in your case, so Spring AOP has no chance to intercept calls to FakeDto (you might need to use LTW)
  • @annotation pointcut designator applies to method executions where the method has the given annotation - in your case the method is toString and it obviously does not have @AutoGenerateCode annotation

here Alexander have shed some light on the problem.

Andrey B. Panfilov
  • 4,324
  • 2
  • 12
  • 18
  • But I don't want the execution to be done with a method (because of what you say about `toString`), I want it to be executed when an object of the `fakeDto` class is instantiated. – Kevin Giraldo Jul 29 '22 at 14:56
  • in that case it is not clear how Q relates to `SpringBoot`, initialization pointcut would be either `@within(AutoGenerateCode) && initialization(*..new(..))` or `@within(AutoGenerateCode) && execution(*..new(..))`, `Spring AOP` supports neither – Andrey B. Panfilov Jul 29 '22 at 20:27
  • Well, but Spring Core and therefore also Spring Boot can easily be configured to use [native AspectJ instead of Spring AOP via LTW (load-time weaving)](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-using-aspectj). I am not sure why the OP wants to intercept instance creation, because he did not explain it. But with this approach he can do it, and Andrey provided some suitable pointcuts already in the his previous comment. – kriegaex Jul 31 '22 at 09:45