坑向: 关于在IDEA中 以XML形式 实现Spring AOP编程时,在xml配置文件中给 连接点的前置通知before 传递参数时出现Unbound pointcut parameter错误的排查
Posted 新来的大狮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了坑向: 关于在IDEA中 以XML形式 实现Spring AOP编程时,在xml配置文件中给 连接点的前置通知before 传递参数时出现Unbound pointcut parameter错误的排查相关的知识,希望对你有一定的参考价值。
坑向: 关于在IDEA中 以XML形式 实现Spring AOP编程时,在xml配置文件中给 连接点的前置通知before 传递参数时出现Unbound pointcut parameter错误的排查
1. 环境介绍
1.1 开发环境
IntelliJ IDEA 2018.3 x64
1.2 spring-config.xml的 beans标签的 相关命名空间属性
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd ">
<!-- 此处省略 -->
</beans>
2.1 错误介绍
在为 连接点 ProceedingJoinPoint 以XML形式 添加 可以传递参数的 before方法时,编译环境提示异常:Unbound pointcut parameter ‘user2’
2.2 原目的 及 错误相关的 代码环境 介绍
2.2.1 原目的
实现基于XML形式的Spring AOP编程,为连接点的添加 带有参数的 前置通知 before
具体思路为: 为一个Bean 创建 输出其信息的接口,然后实现该接口,最终设计一个切面类对该实现的接口方法进行一定的拦截和管理,使其前置通知可以传递被拦截的连接点方法的参数。
2.2.2 错误相关的 代码环境
① 使用的Bean类 User2.java
package com.castle.beans;
import java.io.Serializable;
public class User2 implements Serializable
private Long id;
private String userName;
private String note;
public Long getId()
return id;
public void setId(Long id)
this.id = id;
public String getUserName()
return userName;
public void setUserName(String userName)
this.userName = userName;
public String getNote()
return note;
public void setNote(String note)
this.note = note;
@Override
public String toString()
return id + " " + userName + ": " + note;
② 设计的接口和相应实现类 User2XMLService.java 与 User2XMLServiceImp.java
package com.castle.service;
import com.castle.beans.User2;
public interface User2XMLService
void printUser2(User2 user2);
//=================================================================
package com.castle.service;
import com.castle.beans.User2;
public class User2XMLServiceImp implements User2XMLService
@Override
public void printUser2(User2 user2)
System.err.println(user2);
③ 设计的切面类 User2XMLAspect.java
package com.castle.aspect;
import com.castle.beans.User2;
import org.aspectj.lang.ProceedingJoinPoint;
import static com.castle.tools.PrintTool.*;
public class User2XMLAspect
public void before(User2 user2)
println("XML before... [" + user2.getUserName() + "]");
public void around(ProceedingJoinPoint joinPoint)
println("XML around before...");
try
joinPoint.proceed();
catch (Throwable e)
e.printStackTrace();
println("XML around after...");
public void after()
println("XML after...");
public void afterThrowing()
println("XML after throwing...");
public void afterReturning()
println("XML after returning...");
④ 最终的spring-config2.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd ">
<bean id="user2" class="com.castle.beans.User2">
<property name="id" value="99"/>
<property name="userName" value="Rugal"/>
<property name="note" value="I am the king of fighters"/>
</bean>
<bean id="service1" class="com.castle.service.User2XMLServiceImp"/>
<bean id="aspect1" class="com.castle.aspect.User2XMLAspect"/>
<aop:config>
<aop:aspect ref="aspect1">
<aop:pointcut id="printUser2" expression=
"execution(* com.castle.service.User2XMLServiceImp.printUser2(..))"/>
<aop:before method="before" pointcut=
"execution(* com.castle.service.User2XMLServiceImp.printUser2(..)) and args(user2)"/>
<aop:around method="around" pointcut-ref="printUser2"/>
<aop:after method="after" pointcut-ref="printUser2"/>
<aop:after-returning method="afterReturning" pointcut-ref="printUser2"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="printUser2"/>
</aop:aspect>
</aop:config>
</beans>
⑤ 测试代码
/**
* 测试使用纯XML方法,无注解实现Spring的AOP编程,对连接点方法进行拦截管理
*/
public static void test17()
ApplicationContext xmlContext = new ClassPathXmlApplicationContext("spring-config2.xml");
User2XMLService service = (User2XMLService) xmlContext.getBean("service1");
User2 user2 = (User2) xmlContext.getBean("user2");
service.printUser2(user2);
3.1 错误排查(发现编写的代码正确)
仔细检查
在切面类中关于给before方法传递的参数 为 user2
public void before(User2 user2)
println("XML before... [" + user2.getUserName() + "]");
在xml配置文件中指定切点的表达式中 要求获取的参数 也为 user2,没有发现名称不一致
<aop:before method="before" pointcut=
"execution(* com.castle.service.User2XMLServiceImp.printUser2(..)) and args(user2)"/>
3.2 带着错误执行程序
结果成功运行,并且 切点拦截的连接点方法 被成功执行了 所设计的前置通知before(), 其参数user2的userName也被 成功传递!
public void before(User2 user2)
println("XML before... [" + user2.getUserName() + "]");
userName 被成功提取出来为 Rugal 【此时依然存在Unbound pointcut parameter错误】
4. 编译环境提示错误的原因分析 和 解决方案
4.1 原因分析
也许关于切点的表达式书写正确,并无错误,是编译器或者xml配置文件参照的xsd文件存在一些bug。
即:
<aop:before method="before" pointcut=
"execution(* com.castle.service.User2XMLServiceImp.printUser2(..)) and args(user2)"/>
此语句本无编译错误,IDEA出现误报
4.2 Unbound pointcut parameter错误解决方案
① 修改 IDEA编译的 检查配置, 取消AOP子标签下的 Advice parameters检查
② 压制参数名称检查 ArgNamesErrorsInspection
即添加代码
<!--suppress ArgNamesErrorsInspection -->
<aop:before method="before" pointcut=
"execution(* com.castle.service.User2XMLServiceImp.printUser2(..)) and args(user2)"/>
最终没有了Error的红色下划线提示(变成警告也行):
以上是关于坑向: 关于在IDEA中 以XML形式 实现Spring AOP编程时,在xml配置文件中给 连接点的前置通知before 传递参数时出现Unbound pointcut parameter错误的排查的主要内容,如果未能解决你的问题,请参考以下文章
坑向: 关于对Oracle数据库新建用户后,进行角色授予GRANT “CONNECT“, “RESOURCE“后,用户仍然没有指定角色的相关权限,致拒绝登录ORA-01045问题的探究
关于在Spring中通过注解形式的IoC容器 纯使用 @ComponentScan注解实现对包的自动扫描,实现非XML形式的 注解形式装配Bean类