1

After following so many search results on google on this subject, my Aspect doesn't work still on my spring boot application

I am using spring boot version 2.1.6, which seem to have already spring aop, aspectjweaver and aspectjrt (stand to be corrected). i created an annotation, aspect component and use my annotation on a target class with no success.

here is my annotation class

    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;

    import static java.lang.annotation.ElementType.*;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;

    @Retention(RUNTIME)
    @Target({TYPE, METHOD})
    public @interface AopAudit {
    }

my aspect class

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

    @Aspect
    @Component
    public class AuditAnnotationAspect {
        @Before("execution(* com.rainestech.hrm.modules.settings.entity.ABC.set*(..))")
        public void before(JoinPoint joinPoint) {
    System.out.println("Audit Works!!! = ");
        }
    }

class ABC

@Entity
@AopAudit
public class ABC {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @NotEmpty
    @NotNull
    @Column
    private String name;

    //... getters and setters
}

configuration class

@Configuration
@EnableWebSecurity
@EnableAspectJAutoProxy
public class WebSecurity extends WebSecurityConfigurerAdapter {

}

running the application and running set method on class ABC produce no effect whereas i expect to see Audit Works in the console

Raines
  • 93
  • 2
  • 11
  • What your annotation has to do with the aspect below? `execution(* com.rainestech.hrm.modules.settings.entity.ABC.set*(..))` this statement monitors setters, not an annotation. – Alan Sereb Sep 03 '19 at 18:37
  • @Alan you are right. I removed the reference to the annotation class to see if the problem is with my annotation but didn't work in both case – Raines Sep 03 '19 at 18:40
  • I updated my answer, please make sure you have parent and starter in your pom.xml – Alan Sereb Sep 03 '19 at 18:43
  • @Alan thanks. I do have parent and starter in my pom.xml. will try to add the new line and see if it works – Raines Sep 03 '19 at 18:47
  • Also, take a look at this answer, might help https://stackoverflow.com/a/14604161/6252399 – Alan Sereb Sep 03 '19 at 18:53
  • Assuming you set up Spring AOP in your configuration correctly and the aspect is being picked up by component scan, please make sure that your `ABC` class also has to be a Spring component. In general, everyone here can only speculate about your problem because you are not providing an [MCVE](https://stackoverflow.com/help/mcve) (please read). Spring AOP is always a combination of configuration, aspect and application code. You only provide aspect code, so the rest is pure speculation if anyone likes to help you. – kriegaex Sep 04 '19 at 03:33
  • @kriegaex the aspect is been picked up by component scan and class ABC is an Entity class – Raines Sep 04 '19 at 05:20
  • an entity isn't a spring bean and as such the aspect won't apply. Spring AOP works only for Spring defined and managed beans. The entities are managed by ( I assume) hibernate. If you want to use AOP with that you will need to use either load or compile time weaving instead of the default proxy based approach. – M. Deinum Sep 04 '19 at 05:58
  • @M.Deinum maybe this could really be the problem but how do i use load or compile time weaving? a sample code will be of great help – Raines Sep 04 '19 at 09:37
  • compile time weaving requires changes in your build (AOP will be applied during compilation) load time weaving requires `@EnableLoadTimeWeaving` on your application class. – M. Deinum Sep 04 '19 at 11:27
  • I think its just an invalid path... – Alan Sereb Sep 04 '19 at 14:39
  • 1
    @AlanSereb i have found a way to make it work with my current code and using aspectj maven plugin similar to your reference. pls include it in your answer so i can mark it as accepted. thanks to every one – Raines Sep 04 '19 at 14:47
  • @Raines, done! Make an edit to my answer if you wish. – Alan Sereb Sep 04 '19 at 14:50

2 Answers2

1

First, make sure your pom.xml contains all of these:

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

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
</dependencies>

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.4</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

Second, annotate your configuration with @EnableAspectJAutoProxy, this will enable it.

Third, make sure you update your pointcut:

@Pointcut("@annotation(com.path.to.your.annotation.AopAudit)")
private void auditable() {}

And then use it in your @Before.

@Before("auditable()")

Another important thing to notice is that you cannot execute a method pointcut of which is located on the same class. More info here.

Alan Sereb
  • 2,358
  • 2
  • 17
  • 31
  • Done that with no result on my spring boot application class – Raines Sep 03 '19 at 18:35
  • Spring boot starter-aop is part of the parent pom dependency for version 2.1.6 – Raines Sep 03 '19 at 18:49
  • Double-check your imports, that you import all annotations from the right place. Other than that it's hard to tell. – Alan Sereb Sep 03 '19 at 18:51
  • Then please edit your question to be an [MCVE](https://stackoverflow.com/help/mcve) or upload one to GitHub, ideally incl. Maven build. – kriegaex Sep 04 '19 at 05:56
  • @AlanSereb followed your steps and no result. i have also updated the question including my configuration class, and imports on the aspect class – Raines Sep 04 '19 at 09:34
  • The aspectj plugin finally solves my problem. Always remember to use the latest version of the plugin to avoid issues that have already been solved in later versions – Raines Sep 06 '19 at 04:31
  • I add similar problems, after I qualify Annotation with full package, it worked. – Anand Feb 24 '20 at 05:49
0

Just a very silly remark, as it took me a day :-(. Dont forget to @Autowire youre annotated objects. AOP will typically only work if you resolve everything by the @Component scanned context!

//This will work : Resolve everything trough the @Component container context
@Autowired
FeatureAnnotationAspect aspspectTest;

@Test
public void testAnnotationIntersception() 
{
    log.debug("TestFeatureFlagAspect::testAnnotationIntersception");
   //This wont work! You need to Autowire the object to get all annotations and AOP working!
    //aspcetTest = new FeatureAnnotationAspect();
    aspectTest.Annotate(0);
} 
Roland Roos
  • 1,003
  • 10
  • 4