Spring AOP AspectJ

Spring的AOP可以通过对@AspectJ注解的支持和在XML中配置来实现,本文通过实例简述如何在Spring中使用AspectJ.
一:使用AspectJ注解:
1,启用对AspectJ的支持:
通过在Spring的配置中引入下列元素来启用Spring对AspectJ的支持:
<aop:aspectj-autoproxy />
或者(如果不是使用XSD的话)
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
2,声明一个带有@Aspect注解的类,在这个类中声明那些方法需要被'关注'(利用@Pointcut),在那些时机点进行关注(利用@Before,@AfterReturning等等...),执行'切入'的方法
3,在Spring的配置文件中定义这个'切面'类:任意带有一个@Aspect切面(拥有@Aspect注解)的bean都将被Spring自动识别并用于配置在Spring AOP.
4,使用被Spring管理的bean,在执行被'关注'的方法时,'切入'的方法就会被执行.
一个完整的例子:
需要被'切入'的类:

复制代码
public class Monkey {
    public void stealPeaches(String name) {
        System.out.println(" Monkey " + name + " is stealling peaches...");
    }
   
    public void stealCorns(String name) {
        System.out.println(" Monkey " + name + " is stealling corns...");
    }
}
复制代码

'切面'类:

复制代码
@Aspect
public class Guardian {
    @Pointcut("execution(* com.test.spring.aspectj.Monkey.stealPeaches(..))")
    public void guardOrchard() {
    }

    @Before(value = "guardOrchard()")
    public void guardOrchardBefore() {
        System.out.println("Guardian spotted a monkey is approaching the orchard...");
    }

    @AfterReturning("guardOrchard() && args(name,..)")
    public void guardOrchardAfter(String name) {
        System.out.println("Guardian caught a monkey stealling peaches whoes name is " + name + "...");
    }
   @Around("guardOrchard() && args(name,..)")
  public void guardOrchardAround(ProceedingJoinPoint joinpoint,String name) {
    System.out.println("Guardian guardOrchardAround started ... " + name);
    try {
      joinpoint.proceed();     } catch (Throwable e) {       System.out.println("Guardian guardOrchardAround exception happened ... " + name);     }
    System.out.println("Guardian guardOrchardAround completed ... " + name);   }
@Pointcut(
"execution(* com.test.spring.aspectj.Monkey.stealCorns(..))") public void guardFarm() { } @Before(value = "guardFarm()") public void guardFarmBefore() { System.out.println("Guardian spotted a monkey is approaching the farm..."); } @AfterReturning("guardFarm() && args(name,..)") public void guardFarmAfter(String name) { System.out.println("Guardian caught a monkey stealling corns whoes name is " + name + "..."); } }
复制代码

配置文件:

复制代码
<?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"
    xsi:schemaLocation="    
         http://www.springframework.org/schema/beans    
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
         http://www.springframework.org/schema/aop    
         http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    <!--
        <aop:aspectj-autoproxy /> equals to <bean
        class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"
        />
    -->
    <aop:aspectj-autoproxy />
    <bean id="guardian" class="com.test.spring.aspectj.Guardian" />

    <bean id="monkey" class="com.test.spring.aspectj.Monkey" />

</beans>
复制代码

使用bean:

复制代码
ApplicationContext context = new ClassPathXmlApplicationContext("conf/aspectJAppcontext.xml");
        Monkey monkey = (Monkey) context.getBean("monkey");
        try {
            monkey.stealPeaches("mighty monkey");
            monkey.stealCorns("mighty monkey");
        } catch (Exception e) {
        }
复制代码

运行结果:

复制代码
Guardian spotted a monkey is approaching the orchard...
Guardian guardOrchardAround started ... mighty monkey 
Monkey mighty monkey is stealling peaches...
Guardian caught a monkey stealling peaches whoes name is mighty monkey...
Guardian guardOrchardAround completed ... mighty monkey
Guardian spotted a monkey is approaching the farm...
 Monkey mighty monkey is stealling corns...
Guardian caught a monkey stealling corns whoes name is mighty monkey...
复制代码

二:通过XML配置AspectJ实现AOP:在java类中定义要被'方面'调用的切入方法,在XML中配置.
例子:被'切入'的类,普通java类:

复制代码
public class Monkey {
    public void stealPeaches(String name) {
        System.out.println(" Monkey " + name + " is stealling peaches...");
    }
    
    public void stealCorns(String name,int numberToSteal) {
        System.out.println(" Monkey " + name + " is stealling corns...");
    }
}
复制代码

定义要被'方面'调用的切入方法的类:

复制代码
public class XMLGuardian {
    public void guardOrchardBefore() {
        System.out.println("XMLGuardian spotted a monkey is approaching the orchard...");
    }

    public void guardOrchardAfter() {
        System.out.println("XMLGuardian caught a monkey stealling peaches whoes name is ...");
    }
    public void guardFarmBefore() {
        System.out.println("XMLGuardian spotted a monkey is approaching the farm...");
    }
    public void guardFarmAfter(String name,int num,Object retVal) {
        System.out.println("XMLGuardian caught a monkey stealling " + num + " corns whoes name is ..." + name );
    }
}
复制代码

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"
    xsi:schemaLocation="    
         http://www.springframework.org/schema/beans    
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
         http://www.springframework.org/schema/aop    
         http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
       
    <bean id="guardian" class="com.test.spring.aspectj.XMLGuardian" />
    <bean id="monkey" class="com.test.spring.aspectj.Monkey" />
    <aop:config>
           
        <aop:aspect id="myAspect" ref="guardian">
            <aop:pointcut id="guardOrchard"
                expression="execution(* com.test.spring.aspectj.Monkey.stealPeaches(..))" />
           
            <aop:before pointcut-ref="guardOrchard" method="guardOrchardBefore" />
            <aop:after-returning pointcut-ref="guardOrchard" method="guardOrchardAfter"/>
           
            <aop:pointcut id="guardFarm"
                expression="execution(* com.test.spring.aspectj.Monkey.stealCorns(..))" />
           
            <aop:before pointcut-ref="guardFarm" method="guardFarmBefore" />
            <aop:after-returning pointcut="execution(* com.test.spring.aspectj.Monkey.stealCorns(..)) and args(name,num,..)" returning="retVal"
            method="guardFarmAfter" />
            <!--  arg-names="name1" -->
        </aop:aspect>       
    </aop:config>
</beans>
复制代码

客户端测试代码:

 

复制代码
ApplicationContext context = new ClassPathXmlApplicationContext("conf/xmlaspectJAppcontext.xml");
        Monkey monkey = (Monkey) context.getBean("monkey");
        try {
            monkey.stealPeaches("mighty monkey");
            monkey.stealCorns("mighty monkey",3);
        } catch (Exception e) {
        }
复制代码

运行结果:

XMLGuardian spotted a monkey is approaching the orchard...
 Monkey mighty monkey is stealling peaches...
XMLGuardian caught a monkey stealling peaches whoes name is ...
XMLGuardian spotted a monkey is approaching the farm...
 Monkey mighty monkey is stealling corns...
XMLGuardian caught a monkey stealling 3 corns whoes name is ...mighty monkey

Spring AOP 只支持对bean的方法级的'切入',而且AOP的内部机制和AspectJ有所区别,Spring主要是通过动态代理来实现AOP,使用JDK的动态代理(如果被代理的bean是interface的话)或者CGLIB(如果如果被代理的bean不是interface的话).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xp9802

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值