通过AspectJ注解声明切面固然很好使,但是JDK1.4或以下的版本不支持注解。
Spring还提供了在配置文件中声明切面。
接口Animal和Book:
package com.zzj.aop;
public interface Animal {
public void eat();
public void drink();
}
package com.zzj.aop;
public interface Book {
public void read();
}
目标类:
package com.zzj.aop;
public class Human implements Animal, Book{
@Override
public void eat() {
System.out.println("eat...");
}
@Override
public void drink() {
System.out.println("drink...");
}
@Override
public void read() {
System.out.println("read...");
}
}
切面类:
package com.zzj.aop;
public class XMLAspect {
public void before(){
System.out.println("before...");
}
public void after(){
System.out.println("after...");
}
public void afterReturning(){
System.out.println("afterReturning...");
}
}
spring配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<!-- 定义目标对象 -->
<bean id="man" class="com.zzj.aop.Human"></bean>
<!-- 定义切面 -->
<bean id="aspect" class="com.zzj.aop.XMLAspect"></bean>
<!-- 配置切面 -->
<aop:config>
<aop:pointcut id="afterReturning"
expression="execution(* com.zzj.aop.Human.read(..))"/>
<aop:aspect ref="aspect">
<aop:before method="before"
pointcut="execution(* com.zzj.aop.Human.eat(..))"/>
<aop:after method="after"
pointcut="execution(* com.zzj.aop.Human.drink(..))"/>
<aop:after-returning method="afterReturning"
pointcut-ref="afterReturning"/>
</aop:aspect>
</aop:config>
</beans>
测试:
package com.zzj.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
Animal animal = (Animal) context.getBean("man");
Book book = (Book) animal;
animal.eat();
animal.drink();
book.read();
}
}
输出:
before...
eat...
drink...
after...
read...
afterReturning...
为了让通知能访问当前连接点的信息,可以在通知方法中声明一个类型为JoinPoint的参数。修改切面类:
package com.zzj.aop;
import org.aspectj.lang.JoinPoint;
public class XMLAspect {
public void before(JoinPoint joinPoint){
System.out.println("before "
+ joinPoint.getSignature().getName());
}
public void after(JoinPoint joinPoint){
System.out.println("after "
+ joinPoint.getSignature().getName());
}
public void afterReturning(JoinPoint joinPoint){
System.out.println("afterReturning "
+ joinPoint.getSignature().getName());
}
}
测试输出:
before eat
eat...
drink...
after drink
read...
afterReturning read