Spring AOP引入功能报错:找不到concert.PerformanceImp类型合格Bean
Hey there! Let's figure out why you're getting that NoSuchBeanDefinitionException when trying to implement Spring AOP introductions.
The Root Cause
The core issue lies in how Spring AOP creates proxies by default. When you use @EnableAspectJAutoProxy, Spring defaults to JDK dynamic proxies—which are interface-based. That means the bean in your application context isn't an instance of PerformanceImp; it's a proxy object that implements the Performance interface (and Encoreable, thanks to your introduction logic). So when you try to fetch the bean using PerformanceImp.class, Spring can't locate a bean of that exact class type.
Solutions
Here are two ways to fix this:
Solution 1: Fetch the Bean by Its Interface (Recommended)
This follows Spring's best practice of programming to interfaces. Modify your Main class to retrieve the bean via the Performance interface, then cast it to Encoreable:
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); Performance performance = context.getBean(Performance.class); // Cast to Encoreable since the proxy implements this interface ((Encoreable) performance).performEncore(); performance.perform(); } }
Solution 2: Force CGLIB Proxying (Class-Based Proxies)
If you absolutely need to work directly with the PerformanceImp class, you can tell Spring to use CGLIB proxies instead of JDK dynamic proxies. Update your ConcertConfig by adding proxyTargetClass = true to the @EnableAspectJAutoProxy annotation:
package concert; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration @EnableAspectJAutoProxy(proxyTargetClass = true) // Enable class-based proxies @ComponentScan("concert") public class ConcertConfig { }
With this change, Spring creates a subclass proxy of PerformanceImp, so your original Main code will work as intended. Just note that CGLIB can't proxy final classes or methods, so ensure your target class/methods aren't marked as final.
内容的提问来源于stack exchange,提问作者Meninx - メネンックス

