问题描述
我仍然是 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,在您需要的情况下(希望很少)建议一个没有在接口上声明的方法,或者你在哪里需要将代理对象作为具体类型传递给方法.
所以你有两个选择:
- 尝试从
ApplicationContext
获取 bean 时获取接口. - 启用 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
:
package concert;
import org.springframework.stereotype.Component;
@Component
public class PerformanceImp implements Performance {
public void perform() {
System.out.println("This is the performance function");
}
}
package concert;
public interface Performance {
public void perform();
}
package concert;
public interface Encoreable {
void performEncore();
}
package concert;
import org.springframework.stereotype.Component;
@Component
public class DefaultEncoreable implements Encoreable {
public void performEncore() {
System.out.println("This is the performEncore function");
}
}
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;
}
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:
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
So you have two options:
- Take the interface when trying to get the bean from the
ApplicationContext
. - Enable AOP to target concrete classes instead.
To do this point #2, modify your annotation as follows:
@EnableAspectJAutoProxy(proxyTargetClass = true)
这篇关于没有可用的“concert.PerformanceImp"类型的合格 bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!