No qualifying bean of type 'concert.PerformanceImp' available

无人久伴 提交于 2021-02-05 09:38:06

问题


I am still a beginner in Spring Framework so I tried to code a program about "introduction" in Spring AOP but I am facing an error while compiling. Please find below the classes in the package concert:

PerformanceImp.java

package concert;

import org.springframework.stereotype.Component;

@Component
public class PerformanceImp implements Performance {
    public void perform() {
        System.out.println("This is the performance function");
    }
}

Performance.java

package concert;

public interface Performance {
    public void perform();
}

Encoreable.java

package concert;

public interface Encoreable {
    void performEncore();
}

DefaultEncoreable.java

package concert;

import org.springframework.stereotype.Component;

@Component
public class DefaultEncoreable implements Encoreable {
    public void performEncore() {
        System.out.println("This is the performEncore function");
    }
}

EncoreableIntroducer.java

package concert;
import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class EncoreableIntroducer {
    @DeclareParents(value="concert.Performance+",
            defaultImpl=DefaultEncoreable.class)
    public static Encoreable encoreable;
}

ConcertConfig.java

package concert;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("concert")
public class ConcertConfig {

}

And the main class:

Main.java

package concert;

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


public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(ConcertConfig.class);
        PerformanceImp pi = (PerformanceImp) context.getBean(PerformanceImp.class);
        ((Encoreable) pi).performEncore();
        pi.perform();
    }
}

I am getting the error:

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'concert.PerformanceImp' available

Any help please ?


回答1:


You cannot access the implementation (PerformanceImp) by default, because you enabled AOP, which sets to target interfaces instead of implementation. If you would remove EnableAspectJAutoProxy, you would see the code would work fine.

To understand a bit more about how AOP targeting works, take a look at this Spring Documentation

Spring AOP can also use CGLIB proxies. This is necessary to proxy classes rather than interfaces. CGLIB is used by default if a business object does not implement an interface. As it is good practice to program to interfaces rather than classes; business classes normally will implement one or more business interfaces. It is possible to force the use of CGLIB, in those (hopefully rare) cases where you need to advise a method that is not declared on an interface, or where you need to pass a proxied object to a method as a concrete type.

So you have two options:

  1. Take the interface when trying to get the bean from the ApplicationContext.
  2. Enable AOP to target concrete classes instead.

To do this point #2, modify your annotation as follows:

@EnableAspectJAutoProxy(proxyTargetClass = true)



回答2:


Try:

Performance pi = context.getBean("performanceImp", Performance.class);

instead of:

PerformanceImp pi = (PerformanceImp) context.getBean(PerformanceImp.class);


来源:https://stackoverflow.com/questions/50308666/no-qualifying-bean-of-type-concert-performanceimp-available

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!