1 spring的aop命名空间中,提供了多个元素用来在XML中声明切面,如下所示:
====================================================================================================
aop配置元素 用途
<aop:advisor> 定义AOP通知器
<aop:after> 定义AOP后置通知(不管被通知的方法是否执行成功)
<aop:after-returning> 定义aop返回通知
<aop:after-throwing> 定义aop异常通知
<aop:around> 定义aop环绕通知
<aop:aspect> 定义一个切面
<aop:aspectj-autoproxy> 启用@Aspect注解驱动的切面
<aop:before> 定义一个AOP前置通知
<aop:config> 顶层的AOP配置元素.大多数的<aop:*>元素必须包含在<aop:config>元素内.
<aop:declare-parents> 以透明的方式为被通知的对象引入额外的接口
<aop:pointcut> 定义一个切点
=====================================================================================================
2 切面目标对象
package com.musi.bean;
import org.springframework.stereotype.Component;
@Component
public class Animal {
public void run(){
System.out.println("animal is running .....");
}
public void run(String name){
System.out.println(name+" is running ........");
}
public void run(int times){
System.out.println("animal running times:"+times);
}
}
3 切面
package com.musi.aop.xmlaspect;
import org.springframework.stereotype.Component;
@Component
public class AnimalXmlAspect {
public void beforeRunning(){
System.out.println("Xml before running .......");
}
public void afterRunning(){
System.out.println("Xml after running .......");
}
public void afterReturning(){
System.out.println("Xml afterReturning running .......");
}
public void afterThrowing(){
System.out.println("Xml afterThrowing running .......");
}
}
4 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.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.xsd">
<context:component-scan base-package="com.musi"/>
<!--<aop:aspectj-autoproxy />-->
<aop:config>
<aop:aspect ref="animalXmlAspect">
<aop:before pointcut="execution(* com.musi.bean.Animal.run(..))" method="beforeRunning"/>
<aop:after pointcut="execution(* com.musi.bean.Animal.run(..))" method="afterRunning"/>
<aop:after-returning pointcut="execution(* com.musi.bean.Animal.run(..))" method="afterReturning"/>
<aop:after-throwing pointcut="execution(* com.musi.bean.Animal.run(..))" method="afterThrowing"/>
</aop:aspect>
</aop:config>
<bean id="nimalXmlAspect" class="com.musi.aop.xmlaspect.AnimalXmlAspect" />
<bean id="animalXmlRoundAspect" class="com.musi.aop.xmlaspect.AnimalXmlRoundAspect" />
<bean id="animalXmlArgsAspect" class="com.musi.aop.xmlaspect.AnimalXmlArgsAspect" />
<bean id="xmlEncoreable" class="com.musi.aop.xmlaspect.XmlEncoreableImpl" />
</beans>
简化写法:
<aop:aspect ref="animalXmlAspect">
<aop:pointcut id="run" expression="execution(* com.musi.bean.Animal.run(..))"/>
<aop:before pointcut-ref="run" method="beforeRunning"/>
<aop:after pointcut-ref="run" method="afterRunning"/>
<aop:after-returning pointcut-ref="run" method="afterReturning"/>
<aop:after-throwing pointcut-ref="run" method="afterThrowing"/>
</aop:aspect>
说明:如果想在多个切面中使用同一个pointcut时,则将aop:pointcut元素放入aop:config中即可
5 声明环绕通知
1)切面类
package com.musi.aop.xmlaspect;
import org.aspectj.lang.ProceedingJoinPoint;
public class AnimalXmlRoundAspect {
public void aroundRunning(ProceedingJoinPoint pjp){
try {
System.out.println("xml around before ....");
pjp.proceed();
System.out.println("xml around after ....");
}catch (Throwable throwable) {
System.out.println("xml around trowing ....");
throwable.printStackTrace();
}
}
}
2)xml配置
<aop:aspect ref="animalXmlRoundAspect">
<aop:pointcut id="run" expression="execution(* com.musi.bean.Animal.run(..))"/>
<aop:around pointcut-ref="run" method="aroundRunning"/>
</aop:aspect>
6 未通知传递参数
1)切面类
package com.musi.aop.xmlaspect;
public class AnimalXmlArgsAspect {
public void beforeRunning(int times){
System.out.println("xmlArgs before running times:"+times);
}
public void afterRunning(int times){
System.out.println("xmlArgs after running times:"+times);
}
public void afterReturning(int times){
System.out.println("xmlArgs afterReturning running times:"+times);
}
public void afterThrowing(int times){
System.out.println("xmlArgs afterThrowing running times:"+times);
}
}
2)xml配置
<aop:aspect ref="animalXmlArgsAspect">
<aop:pointcut id="run" expression="execution(* com.musi.bean.Animal.run(int)) and args(times)"/>
<aop:before pointcut-ref="run" method="beforeRunning"/>
<aop:after pointcut-ref="run" method="afterRunning"/>
<aop:after-returning pointcut-ref="run" method="afterReturning"/>
<aop:after-throwing pointcut-ref="run" method="afterThrowing"/>
</aop:aspect>
7 通过切面引入新的功能
1)声明一个接口
package com.musi.aop.xmlaspect;
public interface XmlEncoreable {
void jump();
}
2)为接口添加一个实现类
package com.musi.aop.xmlaspect;
public class XmlEncoreableImpl implements XmlEncoreable {
public void jump() {
System.out.println("this is XmlEncoreableImpl.....");
}
}
3)xml配置
<aop:aspect>
<aop:declare-parents types-matching="com.musi.bean.Animal"
implement-interface="com.musi.aop.xmlaspect.XmlEncoreable"
delegate-ref="xmlEncoreable" />
</aop:aspect>
8 测试类
package com.musi.test.bean;
import com.musi.aop.xmlaspect.XmlEncoreable;
import com.musi.bean.Animal;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:application.xml"})
public class SpringXmlTest {
@Autowired
private Animal animal;
@Test
public void test(){
animal.run(1);
XmlEncoreable xmlEncoreable = (XmlEncoreable)animal;
xmlEncoreable.jump();
}
}