精通Spring4.x--企业应用开发实战
8.5.1@AfterReturning("@annotation()")切点函数详解
代码实现的目标是为NaugthyWaiter类的greetTo()方法实现后置增强,其中greetTo()方法被@NeedTest注解标注。增强类为TestAspect。
增强类:
@Aspect
@Component
public class TestAspect {
@AfterReturning("@annotation(com.smart.anno.NeedTest)")
public void needTestFun() {
System.out.println("needTestFun() executed!");
}
}
目标类:
//@Component
public class NaughtyWaiter implements Waiter {
@NeedTest
public void greetTo(String name) {
System.out.println("NaughtyWaiter: greet to " + name + "...");
}
public void serveT0(String name) {
}
public void joke(String clientName, int times) {
}
}
测试类:
public class PointcutFunTest {
@Test
public void testFun() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("com/smart/aspectj/fun/beans.xml");
Object obj = ctx.getBean("naughtyWaiter");
System.out.println(obj.getClass().getName());
// NaughtyWaiter naughtyWaiter = (NaughtyWaiter) ctx.getBean("naughtyWaiter");
// naughtyWaiter.greetTo("Tom");
// naughtyWaiter.serveT0("Mike");
// naughtyWaiter.joke("Lisa", 3);
}
}
碰到的问题是<aop:aspectj-autoproxy/> 其中<aop:aspectj-autoproxy/>有一个 proxy-target-class属性,默认为false,表示使用JDK动态代理技术织入增强;当配置为<aop:aspectj-autoproxy proxy-target-class="true"/>时,表示使用CGLIB动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则Spring将自动使用CGLIB动态代理。
:
1:
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<aop:aspectj-autoproxy/>
<context:component-scan base-package="com.smart"/>
</beans>
应为NaughtyWaiter实现了Waiter接口,使用JDK动态代理,这种配置方式得到的bean是一个com.sun.proxy.$Proxy12,然后后面红框里的代码就会报错了:
然后添加 proxy-target-class="true" 属性,表示使用CGLIB动态代理织入增强
2:
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<aop:aspectj-autoproxy proxy-target-class="true"/>
<context:component-scan base-package="com.smart"/>
</beans>
问题解决: