public class AOPTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        A a = context.getBean(A.class);
        a.a();
        a.a1();

    }

    @Configuration
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    static class Config {

        @Bean
        public DefaultBeanFactoryPointcutAdvisor defaultBeanFactoryPointcutAdvisor() {
            DefaultBeanFactoryPointcutAdvisor advisor = new DefaultBeanFactoryPointcutAdvisor();
            advisor.setAdvice(testInterceptor());
            NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
            pointcut.setMappedNames("a","a1");
            advisor.setPointcut(pointcut);
            return advisor;
        }

        @Bean
        public TestInterceptor testInterceptor(){
            return new TestInterceptor();
        }
        @Bean
        public A a1(){
            return new A();
        }
    }

    static class A {

        public void a() {
            System.out.println("aaaaaaaaaaa");
            a1();
        }
        public void a1() {
            System.out.println("aaaaaaaaaaa1");
        }
    }


    static class TestInterceptor implements MethodInterceptor {

        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            System.out.println("==========invoke=========");
            return invocation.proceed();
        }
    }

}
Exception in thread "main" org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'AOPTest.Config': Bean with name 'AOPTest.Config' has been injected into other beans [defaultBeanFactoryPointcutAdvisor,testInterceptor] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:623)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
    at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:89)

Comment From: quaff

You should change the method name to any name except a or a1

    @Bean
    public A a1(){
        return new A();
    }

Comment From: sbrannen

Hi @yiliou,

Thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use the issue tracker only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add some more details if you feel this is a genuine bug.


The above is our formal policy regarding questions of this nature.

In any case, I can answer your question.

I've changed the title to "Why can't the method name intercepted by AOP be the same as an @Bean method in an @Configuration class?" to reflect what's actually going on in your example.

The answer is: your pointcut is too broad and attempts to advise the @Bean public A a1() method in your @Configuration class; whereas, I imagine you only meant to advise the methods in the A class.

To fix that you need to add an appropriate ClassFilter to the the pointcut. There are a few concrete implementations of ClassFilter that you can choose from, or you can implement your own. To base the pointcut on methods in a given class (or subclasses thereof) you can use the RootClassFilter.

The following changes make your code work without an exception.

@Bean
public DefaultBeanFactoryPointcutAdvisor defaultBeanFactoryPointcutAdvisor() {
    DefaultBeanFactoryPointcutAdvisor advisor = new DefaultBeanFactoryPointcutAdvisor();
    advisor.setAdvice(testInterceptor());
    NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
    pointcut.setMappedNames("a", "a1");
    pointcut.setClassFilter(new RootClassFilter(A.class));
    advisor.setPointcut(pointcut);
    return advisor;
}

In light of that, I am closing this issue.

Comment From: yiliou

@sbrannen thanks