环境
目标类
public class Dog implements Animal {
@Override
public void run() {
System.out.println("dog run");
}
@Override
public void sleep() {
System.out.println("dog sleep");
}
}
注入bean
<bean id="dog" class="pray.wang.xml.entity.support.Dog"></bean>
切面类
public class LogAspect {
public void start(){
System.out.println("start invoke method");
}
public void end(){
System.out.println("end invoke method");
}
public void ret(){
System.out.println("invoke method return");
}
public void thr(){
System.out.println("invoke method error");
}
}
注入bean
<bean id="logAspect" class="pray.wang.xml.aspect.LogAspect"></bean>
声明切面
要求
- 导入aop命名空间。
- 在Bean的配置文件中,配置切面的Bean,必须要有id属性,供<aop:aspect>元素引用。
- 在Bean的配置文件中,所有Spring AOP的配置都必须定义在<aop:config>元素内部。
- 在<aop:config>元素内部,定义一个<aop:aspect>元素来声明切面,用其ref属性指定切面的Bean。
示例
<bean id="logAspect" class="pray.wang.xml.aspect.LogAspect"></bean>
<aop:config>
<aop:aspect ref="logAspect"></aop:aspect>
</aop:config>
声明切入点
要求
- 必须在<aop:config>元素 或 <aop:aspect>元素下,使用<aop:pointcut>元素声明。
a. 如果声明在<aop:config>下,对<aop:config>下所有切面有效.
b. 如果声明在<aop:aspect>下,只对当前切面有效。 - 基于XML声明的AOP,不允许在切入点表达式中,用名称引用其他表达式。
示例
<aop:config>
<aop:pointcut id="sleep" expression="execution(* pray.wang.xml..Dog.*(..))"></aop:pointcut>
<aop:aspect ref="logAspect"></aop:aspect>
</aop:config>
<aop:config>
<aop:aspect ref="logAspect">
<aop:pointcut id="sleep" expression="execution(* pray.wang.xml..Dog.*(..))"></aop:pointcut>
</aop:aspect>
</aop:config>
声明切面的通知
要求
- 通知声明在<aop:aspect>元素下,每种通知对应一个XML元素。
a. 前置通知:<aop:before>
b. 后置通知:<aop:after>
c. 返回通知:<aop:after-returning>
d. 异常通知:<aop:after-throwing>
e. 环绕通知:<aop:around> - method属性指定切面中的通知方法的名称,pointcut-ref 指向<aop:pointcut>元素的id属性。
示例
<aop:config>
<aop:aspect ref="logAspect">
<aop:before method="start" pointcut="execution(* pray.wang.xml..*.run(..))"></aop:before>
<aop:after method="end" pointcut="execution(* pray.wang.xml..*.run(..))"></aop:after>
<aop:after-returning method="ret" pointcut="execution(* pray.wang.xml..*.run(..))"></aop:after-returning>
<aop:after-throwing method="thr" pointcut="execution(* pray.wang.xml..*.run(..))"></aop:after-throwing>
</aop:aspect>
</aop:config>
<aop:config>
<aop:aspect ref="logAspect">
<aop:pointcut id="sleep" expression="execution(* pray.wang.xml..Dog.*(..))"></aop:pointcut>
<aop:before method="start" pointcut-ref="sleep"></aop:before>
<aop:after method="end" pointcut-ref="sleep"></aop:after>
<aop:after-returning method="ret" pointcut-ref="sleep"></aop:after-returning>
<aop:after-throwing method="thr" pointcut-ref="sleep"></aop:after-throwing>
</aop:aspect>
</aop:config>
*声明环绕通知
创建切面类
public class AroundAspect {
public Object aro(ProceedingJoinPoint pjp){
try {
System.out.println("before");
Object proceed = pjp.proceed();
System.out.println("after");
return proceed;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
}
声明切面的Bean
<bean id="aroundAspect" class="pray.wang.xml.aspect.AroundAspect"></bean>
声明通知
<!--环绕通知-->
<aop:config>
<aop:pointcut id="arou" expression="execution(* pray.wang.xml..Dog.run(..))"></aop:pointcut>
<aop:aspect ref="aroundAspect">
<aop:around method="aro" pointcut-ref="arou"></aop:around>
</aop:aspect>
</aop:config>
*为通知传递参数
创建切面类
public class ArgsAspect {
public void outSpeed(Double speed){
System.out.println("speed is "+speed);
}
}
声明切面的Bean
<bean id="argsAspect" class="pray.wang.xml.aspect.ArgsAspect"></bean>
声明通知
<!--传递参数-->
<aop:config>
<aop:pointcut id="sp" expression="execution(* pray.wang.xml..*.run(..)) and args(speed)"></aop:pointcut>
<aop:aspect ref="argsAspect">
<aop:before method="outSpeed" arg-names="speed" pointcut-ref="sp"></aop:before>
</aop:aspect>
</aop:config>
必须保证切点参数名和通知里面的参数名一致,若通知里面的参数名不指定,则默认使用方法里面的形参的名字。
网友评论