没有可用的“concert.PerformanceImp"类型的合格 bean [英] No qualifying bean of type 'concert.PerformanceImp' available

查看:30
本文介绍了没有可用的“concert.PerformanceImp"类型的合格 bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍然是 Spring Framework 的初学者,所以我尝试在 Spring AOP 中编写一个关于介绍"的程序,但在编译时遇到错误.请在concert包中找到下面的类:

<块引用>

PerformanceImp.java

打包演唱会;导入 org.springframework.stereotype.Component;@成分公共类 PerformanceImp 实现 Performance {公共无效执行(){System.out.println("这是性能函数");}}

<块引用>

性能.java

打包演唱会;公共接口性能{公共无效执行();}

<块引用>

Encoreable.java

打包演唱会;公共接口 Encoreable {void performEncore();}

<块引用>

DefaultEncoreable.java

打包演唱会;导入 org.springframework.stereotype.Component;@成分公共类 DefaultEncoreable 实现 Encoreable {公共无效 performEncore() {System.out.println("这是performEncore 函数");}}

<块引用>

EncoreableIntroducer.java

打包演唱会;导入 org.aspectj.lang.annotation.Aspect;导入 org.aspectj.lang.annotation.DeclareParents;导入 org.springframework.stereotype.Component;@成分@方面公共类 EncoreableIntroducer {@DeclareParents(value="concert.Performance+",defaultImpl=DefaultEncoreable.class)public static Encoreable encoreable;}

<块引用>

ConcertConfig.java

打包演唱会;导入 org.springframework.context.annotation.Bean;导入 org.springframework.context.annotation.ComponentScan;导入 org.springframework.context.annotation.Configuration;导入 org.springframework.context.annotation.EnableAspectJAutoProxy;导入 org.springframework.stereotype.Component;@配置@EnableAspectJAutoProxy@ComponentScan("音乐会")公共类 ConcertConfig {}

还有主类:

<块引用>

Main.java

打包演唱会;导入 org.springframework.context.ApplicationContext;导入 org.springframework.context.annotation.AnnotationConfigApplicationContext;公共课主要{公共静态无效主(字符串 [] args){ApplicationContext context = new AnnotationConfigApplicationContext(ConcertConfig.class);PerformanceImp pi = (PerformanceImp) context.getBean(PerformanceImp.class);((Encoreable) pi).performEncore();pi.perform();}}

我收到错误:

线程main"org.springframework.beans.factory.NoSuchBeanDefinitionException 中的异常:没有可用的concert.PerformanceImp"类型的合格bean

有什么帮助吗?

解决方案

默认情况下您无法访问实现 (PerformanceImp),因为您启用了 AOP,它设置为目标接口而不是实现.如果您删除 EnableAspectJAutoProxy,您会看到代码可以正常工作.

要进一步了解 AOP 定位的工作原理,请查看此 Spring 文档

<块引用>

Spring AOP 也可以使用 CGLIB 代理.这是代理所必需的类而不是接口.如果企业在默认情况下使用 CGLIB对象不实现接口.因为这是很好的做法编程到接口而不是类;商务舱正常将实现一个或多个业务接口.有可能强制使用 CGLIB,在您需要的情况下(希望很少)建议一个没有在接口上声明的方法,或者你在哪里需要将代理对象作为具体类型传递给方法.

所以你有两个选择:

  1. 尝试从 ApplicationContext 获取 bean 时获取接口.
  2. 启用 AOP 以针对具体类.

要做到这一点#2,请按如下方式修改您的注释:

@EnableAspectJAutoProxy(proxyTargetClass = true)

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 ?

解决方案

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)

这篇关于没有可用的“concert.PerformanceImp"类型的合格 bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆