使用 Spring AOP
,尝试创建 Pointcut
使用指示符 args
虽然不提供任何类型,但会导致一系列异常,从 BeanCurrentlyInCreationException
例子
object _001_Spring_AOP_Pointcut_Args_NoArgs {
open class BeanA {
open fun m() {
println("BeanA#m()")
}
}
@Aspect
class AspectA {
@Pointcut("args()")
private fun pc_noArgs() = Unit
@After("sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs.AspectA.pc_noArgs()")
private fun ac_noArgs() = println("ac_noArgs")
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
open class Config {
@Bean
open fun beanA(): BeanA = BeanA()
@Bean
open fun aspectA(): AspectA = AspectA()
}
fun runJava() {
AnnotationConfigApplicationContext(Config::class.java)
}
}
run方法
@Test
fun test_run() {
_001_Spring_AOP_Pointcut_Args_NoArgs.runJava()
}
异常摘要
在上下文初始化过程中遇到异常-取消刷新尝试:org.springframework.beans.factory.beancreationexception:创建名为'beana'的bean时出错,该bean在sero4.spring.z中定义。\u 001\u spring\u aop\u pointcut\u args\u noargs$config:通过工厂方法示例化bean失败;嵌套异常为org.springframework.beans.beaninstantiationexception:未能示例化[sero4.spring.z\u added.\u 001\u spring\u aop\u pointcut\u args\u noargs$beana]:工厂方法“beana”引发异常;嵌套的异常是org.springframework.beans.factory.beancreationexception:创建名为'aspecta'的bean时出错,该bean在sero4.spring.z中定义。\u 001\u spring\u aop\u pointcut\u args\u noargs$config:通过工厂方法示例化bean失败;嵌套异常为org.springframework.beans.beaninstantiationexception:未能示例化[sero4.spring.z\u added.\u 001\u spring\u aop\u pointcut\u args\u noargs$aspecta]:工厂方法“aspecta”引发异常;嵌套异常为org.springframework.beans.factory.beancurrentlyincreationexception:创建名为“aspecta”的bean时出错:请求的bean当前正在创建中:是否存在无法解析的循环引用?
2条答案
按热度按时间sigwle7e1#
args()与执行(**())
这是一种不寻常的拦截所有没有参数的方法的方式。我宁愿把它说得更清楚,更实用
execution(* *())
相反。如果您曾经从springaop迁移到aspectj,您会注意到args()
匹配所有类型的切入点,例如。call
,initialization
,preinitialization
,staticinitialization
,get
构造函数调用/执行,而不带参数。切入点范围
不过,在 Spring aop中,你的问题可能是另一个:你的切入点太宽了。它匹配springbean中的许多连接点,也匹配spring或第三方类本身。所以你想限制切入点的范围,例如
何时(不)在切入点中使用完全限定类名
顺便说一句,如果切入点与使用它的通知定义在同一个类中,则不必使用完全限定的类名,即,而不是
你可以用
内联切入点
如果你不打算在其他建议中重复使用相同的切入点,那就放弃它吧
@Pointcut
并定义一个内联切入点,例如建议应该是公开的
虽然可以定义
@Pointcut
方法作为私有的,如果不从其他类引用它,则@After
建议应该是公开的。它可能在SpringAOP中起作用,但与约定背道而驰。同样,如果迁移到aspectj,甚至会出现编译错误,因为aspectj建议必须是公共的。ttygqcqt2#
共享的代码失败,出现以下异常-
,当
pointcut
表达式在方面类所在的包中有一个作用域。例子:
bean的完全限定名:
像下面这样的切入点表达式将失败:
然而,以下切入点表达式成功:
在我看来,例外是因为
pointcut
在初始化期间针对方面的框架方法。要解决异常,可以将bean移动到特定的包中,并微调pointcut
那个包裹的表达式。