AOP编程时定义切面时需要注意的事
@Around
以@Around
注解拦截构造方法(Constructor)时切面定义只能用call方式而不能是execution,否则 ProceedingJoinPoint.proceed()
返回的是null,得不到构造的实例。
execution
execution切入点要修改对象内部,所以PCW模式下如果对第三方库定义切面,不建议使用这种方式,要改为call.
因为PCW如果要以execution方式切入,就会在当前项目的 target/classes下(maven环境)重新生成第三方库的class.把原本简单的事搞复杂了。
call
在使用AspectJ进行AOP编程时,AspectJ不能对没有公开构造方法的类或对静态方法进行调用(call)操作。AspectJ的切面(aspect)中的切点(pointcut)用来指定对哪些类或方法进行拦截,但如果目标对象没有公开的构造方法,AspectJ将无法创建该类的代理对象,从而无法完成AOP操作。
解决方法:
确保目标类有一个或多个公开的构造方法。如果是第三方库中的类,可能需要查看文档或源代码来确定是否可以修改。
如果是静态方法,可以考虑使用非静态方法,并通过单例模式(Singleton pattern)来保证全局唯一性,或者使用AspectJ提供的额外方法(如@Pointcut(“execution(static * .(…))”)来处理静态方法。
如果不希望修改原始类,可以考虑使用AspectJ提供的Percflow或Percflowbelow切点指定器,但这通常需要更复杂的表达式和特定的环境配置。
如果是编译时期错误,可以检查AspectJ的编译和加载配置是否正确。
请根据具体情况选择合适的解决方法。
参考资料
《AspectJ: intercept constructor when method reference is used》
《AspectJ pointcut on constructor object》