Spring文档中“bean PCD不适用于@Aspect模型中声明的切面”表述的含义解析及实操疑问解答
嘿,这个问题确实容易让人绕晕,我给你拆解清楚:
先解释第一句话的含义
文档里的... not available for aspects declared in the @Aspect model,这里的**@Aspect模型特指原生AspectJ的@AspectJ风格切面**——也就是完全基于原生AspectJ织入机制(比如编译时织入、加载时织入)创建的切面,和Spring AOP框架无关。这句话的核心意思是:bean这个切入点指示器(PCD)是Spring为自己的AOP框架量身定制的扩展,原生AspectJ根本不识别它,所以如果你的切面是用原生AspectJ方式声明的@Aspect类,那bean PCD就没法用。
再说说你遇到的“矛盾”点
你能在自己写的@Aspect类里用@Pointcut("bean(*Service)"),是因为你用的是Spring AOP框架实现的@AspectJ风格切面,而非原生AspectJ的。Spring AOP对@Aspect注解做了适配,把这类类当作Spring AOP的切面来处理,自然支持自己扩展的bean PCD。
文档5.4.3节的注释其实是把概念明确区分开了:
bean PCD仅在Spring AOP中受支持,原生AspectJ织入并不支持它。它是Spring针对AspectJ定义的标准PCD所做的特定扩展,因此不适用于@Aspect模型中声明的切面。
这里的“@Aspect模型”还是指原生AspectJ的@AspectJ模型,不是Spring AOP里的用法。原生AspectJ的织入过程完全脱离Spring,它不知道Spring容器里的bean概念,所以肯定不支持bean这种Spring特有的PCD。而我们日常在Spring项目中写的@Aspect类,是通过@EnableAspectJAutoProxy等方式交给Spring AOP代理的,属于Spring AOP的范畴,所以能正常使用bean指示器。
举个直观的例子:如果你的项目用了原生AspectJ的编译时织入(比如配置AspectJ Maven插件,把切面逻辑直接编译进目标类),这时你在@Aspect类里写bean()切入点就会报错,因为原生AspectJ根本不认这个语法;但如果只是用Spring AOP的动态代理方式,那完全没问题。
内容的提问来源于stack exchange,提问作者Ander

