0
votes

Could someone please help me to understand what am I missing here

  1. The code works fine if I remove @EnableAspectJAutoProxy from StudentModuleConfig
  2. The code also works fine I define advice as @Before("execution(* fi*(..))") with @EnableAspectJAutoProxy and advice works

Problem happens with @Before("execution(* *(..))"), not sure why

Student.java

package com.springpeople.training.assignment.student.domain;

import java.util.Collection;
import java.util.Collections;

import com.springpeople.training.assignment.course.domain.Course;

public class Student {
    private String name;
    private String surname;
    private Collection<Course> enrolledCourses = Collections.emptyList();
    private String userName;

    public Student() {
    }

    public Student(String name, String surname, String userName, Course... enrolledCourses) {
        super();
        this.name = name;
        this.surname = surname;
        this.userName = userName;
        for (Course course : enrolledCourses) {
            this.enrolledCourses.add(course);
        }
    }

    public Student(String name, String surname, String userName) {
        super();
        this.name = name;
        this.surname = surname;
        this.userName = userName;
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", surname=" + surname + ", enrolledCourses=" + enrolledCourses + ", userName="
                + userName + "]";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public Collection<Course> getEnrolledCourses() {
        return enrolledCourses;
    }

    public void setEnrolledCourses(Collection<Course> enrolledCourses) {
        this.enrolledCourses = enrolledCourses;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

}

StudentRepository

package com.springpeople.training.assignment.student.repositoy;

import java.util.Collection;

import com.springpeople.training.assignment.course.domain.Course;
import com.springpeople.training.assignment.student.domain.Student;

public interface StudentRepository {
    Collection<Student> findAllStudentByCourse(Course course);
}

StudentRepositoryImpl.java

package com.springpeople.training.assignment.student.repositoy;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import com.springpeople.training.assignment.course.domain.Course;
import com.springpeople.training.assignment.student.domain.Student;


public class StudentRepositoryImpl implements StudentRepository {

    public StudentRepositoryImpl() {
        System.out.println("StudentRepositoryImpl constructor invoked");
    }

    public void init() {
        System.out.println("StudentRepositoryImpl.init() invoked");
    }

    public void destroy() {
        System.out.println("StudentRepositoryImpl.destroy() invoked");
    }

    @Override
    public Collection<Student> findAllStudentByCourse(Course course) {
        List<Student> students = new ArrayList<>();
        if (Objects.nonNull(course) && "Spring".equals(course.getName())) {
            students.add(new Student("A", "a", "aa"));
            students.add(new Student("B", "b", "bb"));
        }
        return students;
    }

}

StudentService

package com.springpeople.training.assignment.student.service;

import java.util.Collection;

import com.springpeople.training.assignment.course.domain.Course;
import com.springpeople.training.assignment.student.domain.Student;

public interface StudentService {
    Collection<Student> findAllStudentByCourse(Course course);
}

StudentServiceImpl

package com.springpeople.training.assignment.student.service;

import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;

import com.springpeople.training.assignment.course.domain.Course;
import com.springpeople.training.assignment.student.domain.Student;
import com.springpeople.training.assignment.student.repositoy.StudentRepository;

public class StudentServiceImpl implements StudentService {

    private StudentRepository repository;

    public StudentServiceImpl() {
        System.out.println("StudentServiceImpl constructor invoked");
    }

    public StudentServiceImpl(StudentRepository repository) {
        this.repository = repository;
    }

    public void init() {
        System.out.println("StudentServiceImpl.init() invoked");
    }

    public void destroy() {
        System.out.println("StudentServiceImpl.destroy() invoked");
    }

    @Override
    public Collection<Student> findAllStudentByCourse(Course course) {
        return repository.findAllStudentByCourse(course);
    }

    public void setStudentRepository(StudentRepository studentRepositoryBean) {
        repository = studentRepositoryBean;
    }

}

LoggingAspect

package com.springpeople.training.assignment.student.aspect;

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

@Component
@Aspect
public class LoggingAspect {

    @Before("execution(* *(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("LoggingAspect.logBefore(): "+joinPoint.getSignature().getName());
    }

}

StudentModuleConfig.java

package com.springpeople.training.assignment.student;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

import com.springpeople.training.assignment.student.aspect.LoggingAspect;
import com.springpeople.training.assignment.student.repositoy.StudentRepository;
import com.springpeople.training.assignment.student.repositoy.StudentRepositoryImpl;
import com.springpeople.training.assignment.student.service.StudentService;
import com.springpeople.training.assignment.student.service.StudentServiceImpl;

@Configuration
@EnableAspectJAutoProxy
public class StudentModuleConfig {

    @Bean
    public StudentRepository getStudentRepositoryBean() {
        return new StudentRepositoryImpl();
    }

    @Bean
    public StudentService getStudentServiceBean() {
        StudentServiceImpl studentServiceImpl = new StudentServiceImpl();
        studentServiceImpl.setStudentRepository(getStudentRepositoryBean());
        return studentServiceImpl;
    }

    @Bean
    public LoggingAspect getLoggingAspectBean() {
        return new LoggingAspect();
    }
}

App2.java

package com.springpeople.training.assignment;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.springpeople.training.assignment.course.domain.Course;
import com.springpeople.training.assignment.student.StudentModuleConfig;
import com.springpeople.training.assignment.student.service.StudentService;

public class App2 
{
    public static void main( String[] args ) throws InterruptedException
    {
        ApplicationContext container = new AnnotationConfigApplicationContext(StudentModuleConfig.class);
        StudentService service3 = container.getBean(StudentService.class);
        System.out.println(service3.findAllStudentByCourse(new Course("Spring", 12, "advance")));
    }
}

Exception: Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getStudentRepositoryBean' defined in com.springpeople.training.assignment.student.StudentModuleConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.springpeople.training.assignment.student.repositoy.StudentRepository]: Factory method 'getStudentRepositoryBean' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getLoggingAspectBean' defined in com.springpeople.training.assignment.student.StudentModuleConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.springpeople.training.assignment.student.aspect.LoggingAspect]: Factory method 'getLoggingAspectBean' threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'getLoggingAspectBean': Requested bean is currently in creation: Is there an unresolvable circular reference? at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:590)

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.springpeople.training.assignment.student.repositoy.StudentRepository]: Factory method 'getStudentRepositoryBean' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getLoggingAspectBean' defined in com.springpeople.training.assignment.student.StudentModuleConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.springpeople.training.assignment.student.aspect.LoggingAspect]: Factory method 'getLoggingAspectBean' threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'getLoggingAspectBean': Requested bean is currently in creation: Is there an unresolvable circular reference? at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getLoggingAspectBean' defined in com.springpeople.training.assignment.student.StudentModuleConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.springpeople.training.assignment.student.aspect.LoggingAspect]: Factory method 'getLoggingAspectBean' threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'getLoggingAspectBean': Requested bean is currently in creation: Is there an unresolvable circular reference? at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:590)

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.springpeople.training.assignment.student.aspect.LoggingAspect]: Factory method 'getLoggingAspectBean' threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'getLoggingAspectBean': Requested bean is currently in creation: Is there an unresolvable circular reference? at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:582) ... 38 more Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'getLoggingAspectBean': Requested bean is currently in creation: Is there an unresolvable circular reference? at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:339) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:215)

Edit If I do the following, it works..

Removed the following from StudentModuleConfig

@Bean
    public LoggingAspect getLoggingAspectBean() {
        return new LoggingAspect();
    }

And added @ComponantScan in the StudentModuleConfig as follows:

@ComponentScan(basePackages= {"com.springpeople.training.assignment.student.aspect"})

But I still have the question why it didn't work if I declare the LoggingAspect as a bean by using @Bean annotation, is this not the way we can create a container managed bean

1
Thanks for your comment, while running App2, some exception is being thrown, as I mentioned earlier the code works fine if I run advice for method starts with "fi" but if I want run advice for all method (represented by *) it failsmanish2aug
One more thing, if I do not expose the LoggingAspect as a bean in StudentModuleConfig and just instruct the container to find it using componantScan it works. I did the following to get it work Removed the following from StudentModuleConfig @Bean public LoggingAspect getLoggingAspectBean() { return new LoggingAspect(); }manish2aug
i'm not a java specialist, so I would recommend placing try/catch blocks around and check whether any exception is being thrown in the calls made during the bean initialization. The message you see usually is related to exception being thrown on bean initialization, but I could not find anything obvious here (maybe LoggingAspect?). Also add the 'java' tag to your question, so that more people will find it and possibly answer it. Good luck!sɐunıɔןɐqɐp

1 Answers

0
votes

Avoid trying to instantiate the aspect bean manually, let Spring take care of its lifecycle. So to remove StudentModuleConfig.getLoggingAspectBean() and add @ComponentScan to the class instead is the right thing to do, as you already found out.

Not being a Spring user (I only have a Spring AOP playground project for answering questions like yours), I can only speculate about what might be happening there. But I think that somehow Spring thinks you want to create a regular Spring bean, not knowing that it is an aspect instance, and tries to apply the aspect to it because of your global catch-all pointcut. Thus the mentioned circular reference in the error log. Note that an aspect is not a normal bean even though it is a @Component, e.g. aspects cannot advise themselves.