代码示例:
Performance接口
public interface Performance {
void perform(String performContent);
}
Performance实现类
@Component
public class Concert implements Performance {
@Override
public void perform(String performContent) {
System.out.println(performContent + "表演中。。。");
}
}
切面类
public class Audience {
public void performance(String performContent) {};
public void sliencingPhones(String performContent){
System.out.println(performContent);
System.out.println("Sliencing cell phones");
}
public void watchPerformance(ProceedingJoinPoint jp) {
try {
System.out.println("Taking seats");
jp.proceed();
System.out.println("CLAP CLAP CLAP!!!");
} catch (Throwable e) {
System.out.println("Demand a refund");
e.printStackTrace();
}
}
}
新功能接口
public interface Encoreable {
void performEncore();
}
新功能接口实现
public class DefaultEncoreable implements Encoreable {
@Override
public void performEncore() {
System.out.println("Encoreable performEncore!!!");
}
}
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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.zachary.aop"/>
<bean id="defaultEncoreable" class="com.zachary.aop.DefaultEncoreable"/>
<aop:config>
<!-- <aop:around pointcut="execution(com.zachary.aop.Performance.perform(..))" method="watchPerformance"/> -->
<aop:pointcut id="performance"
expression="execution(* com.zachary.aop.Performance.perform(..)) && args(performContent)" />
<aop:aspect ref="audience">
<aop:before
pointcut-ref="performance"
method="sliencingPhones"/>
<aop:around
pointcut-ref="performance"
method="watchPerformance"/>
<aop:declare-parents
types-matching="com.zachary.aop.Concert"
implement-interface="com.zachary.aop.Encoreable"
delegate-ref="defaultEncoreable" />
<!-- <aop:declare-parents
types-matching="com.zachary.aop.Concert"
implement-interface="com.zachary.aop.Encoreable"
default-impl="com.zachary.aop.DefaultEncoreable" /> -->
</aop:aspect>
</aop:config>
<aop:aspectj-autoproxy />
</beans>
测试
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(classes = ConcertConfig.class)
@ContextConfiguration(locations = "classpath:aop-config.xml")
public class ConcertConfigTest {
@Autowired
private Performance concert;
@Test
public void test() {
concert.perform("perform1");
Encoreable encoreable = (Encoreable) concert;
encoreable.performEncore();
}
}
Output:
pperform1
Sliencing cell phones
Taking seats
perform1
perform1表演中。。。
CLAP CLAP CLAP!!!
Encoreable performEncore!!!
通过切面引入新功能在xml中的两种形式:
<aop:declare-parents
types-matching="com.zachary.aop.Concert"
implement-interface="com.zachary.aop.Encoreable"
delegate-ref="defaultEncoreable" />
<!-- <aop:declare-parents
types-matching="com.zachary.aop.Concert"
implement-interface="com.zachary.aop.Encoreable"
default-impl="com.zachary.aop.DefaultEncoreable" /> -->
问题总结
报错内容:Caused by: java.lang.IllegalArgumentException: error at ::0 formal unbound in pointcut
报错原因:
切点定义为execution(* com.zachary.aop.Performance.perform(…))
sliencingPhones有一个String类型的参数,pointcut定义是没有定义导致报错。
“*”’后面没有空格,也会导致类似的报错。