Spring AOP

    Aop是Aspect-Oriented Programming(面向方面编程或面向切面编程)的简称。在Spring平台功能中,AOP是一个核心模块,Spring将AOP框架与IoC容器紧密集成,从而为使用AOP提供最大便利。

1、Spring AOP相关术语
  •     通知(Advice)
      在AOP中,切面的工作成为通知,通知定义了切面是什么以及何时使用。
      Spring切面可以应用5种类型的通知:
      Before—在方法调用前调用通知
      After—在方法调用后调用通知,不论方法执行成功与否
      After-returning—在方法调用成功执行后调用通知
      After-throwing—在方法调用抛出异常后调用通知
      Around—通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为
  •      连接点(Joinpoint)
      连接点是在应用执行过程中能够无插入切面的一个点。这个点可以是调用方法时、抛出异常时。切面代码可以插入到应用的正常流程中。
  •      切点(Pointcut)
      如果通知定义了切面“什么”和”何时“,那么切点就定义了”何处“。切点定义会匹配通知所要植入的一个或多个连接点。
  •      切面(Aspect)
     切面是通知和切点的结合。通知和切点共同定义了切面的全部内容——它是什么,在何时何地完成功能。
2、 Spring提供的4种实现AOP的方式:
  • 经典的基于代理的AOP
  • @AspectJ注解驱动的切面
  • 纯POJO切面
  • 注入式AspectJ切
纯POJO切面的配置AOP
1)首先实现一个简单的Spring Bean类,用于测试切面
class AopTestClass{

public AopTestClass() {
    }
public  void testNormalAdvice(  ) throws Exception {
        System.out.println(" Test  normal advice!!!");
//  throw new Exception("exception happen!!");
}
public  void testAroundAdvice(){
        System.out.println(" Test  around advice!!!");
}
}
2)然后实现一个待切入的切面实现类,该类中定义了将要切入的通知方法
class PrintAspectTrace{

public  void before_(){

        System.out.println("This before !");
}
public  void after_return_(){

        System.out.println("This after_return_ !");
}
public  void after_throw_(Exception ex){

        System.out.println("This after_throw_ !" +ex.getMessage());
}
public  void after_(){

        System.out.println("This after_ !");
}
public void around_(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("around  --- before");
pjp.proceed();
System.out.println("around  --- after");

}

}
3)在Bean xml配置文件中,配置相关切面。注意:首先要引入aop命名空间
<bean id="testAop" class="com.xl.AopTestClass"/> <!-- 定义aop测试bean -->
<bean id="traceAspect"  class="com.xl.PrintAspectTrace"  />  <!-- 定义aop切面bean -->

<aop:config>
 <!-- 配置aop切面-->
  <aop:aspect  ref="traceAspect">
      <!-- 定义切点为AopTestClass类的testNormalAdvice方法-->
      <aop:pointcut id="pt" expression="execution(* com.xl.AopTestClass.testNormalAdvice(..) )"/>
      <!-- 配置aop前置通知-->
      <aop:before method="before_" pointcut-ref="pt" />

      <aop:after-returning method="after_return_"  pointcut-ref="pt"  />

      <aop:after-throwing method="after_throw_" throwing="ex" pointcut-ref="pt"/>
      <!-- 配置aop切面后置通知-->
      <aop:after method="after_" pointcut-ref="pt"/>

  </aop:aspect>
  <aop:aspect  ref="traceAspect">
        <aop:pointcut id="pt1" expression="execution(* com.xl.AopTestClass.testNormalAdvice(..) )"/>
        <!-- 配置aop切面环绕通知-->
        <aop:around method="around_" pointcut-ref="pt1"/>
  </aop:aspect>

</aop:config>

4)切面应用测试
AopTestClass aopTestClass = (AopTestClass) context.getBean("testAop");
try {
    aopTestClass.testNormalAdvice();
} catch (Exception e) {
//  e.printStackTrace();
}
5)结果
This before !
around  --- before
 Test  normal advice!!!
around  --- after
This after_return_ !
This after_ !
AspectJ注解驱动的切面
   
1)同样的实现一个普通POJO bean,作为设置切面的目标
class AopTestClass1{
public AopTestClass1() {
    }

public  void testNormalAdvice () throws  Exception{
        System.out.println(" Test  normal advice!!!");
//  testAroundAdvice();

      //  throw new Exception("EX  HAPPENED!!") ;
}

public  void testAroundAdvice(){
        System.out.println(" Test  around advice!!!");
}

public  void testNormalAdviceWithArgs(String normalArg){
        System.out.println(" Test  normal advice  with arg!!!"+normalArg);
}
}
2)实现切面类,并且在该类中通过 @Aspect注解来声明切点以及通知
@Aspect
class PrintAspectTrace1{

@Pointcut("execution( * com.xl.AopTestClass1.testNormalAdvice())")
public void test(){

     }

@Before(value = "test()")
public  void before_(){

        System.out.println("This before_ !" );
}
@AfterReturning( pointcut = "test()")
public  void after_return_(){

        System.out.println("This after_return_ !");
}
@AfterThrowing(pointcut = "test()" ,throwing ="ex" )
public  void after_throw_(Exception ex){

        System.out.println("This after_throw_ !" +ex.getMessage());
}
@After("test()" )
public  void after_(){

        System.out.println("This after_ !");
}

@Around("test()")
public void around_(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("around  --- before");
        try{
            pjp.proceed();
}
catch ( Exception e){
//  System.out.println("around  --- catch exception " +e);
throw e;
}

        System.out.println("around  --- after");

}

@Pointcut("execution( * com.xl.AopTestClass1.testAroundAdvice())")
public void test1(){

    }
@Before(value = "test1()")
public  void before_test_Around(){

        System.out.println("This before_test_Around !" );
}


}
@Aspect
class PrintAspectTrace2{


@Pointcut("execution( * com.xl.AopTestClass1.testNormalAdviceWithArgs(..))&&args(normalArg,..)&&target(bean)")
public void test(Object bean,String normalArg){

    }

@Before("test(bean,normalArg)")
public  void before_(Object bean,String normalArg){

        System.out.println("This before_ !" +normalArg +bean.toString());
}
@Around("test(bean,normalArg)")
public void around_(ProceedingJoinPoint pjp,Object bean,String normalArg) throws Throwable{
        System.out.println("around  --- before"+normalArg+bean.toString());
pjp.proceed(new Object[]{ normalArg });

System.out.println("around  --- after"+normalArg+bean.toString());
//  throw new Exception("exception happen!!") ;
}

}
3) 在Bean xml配置文件中,配置相关bean,注意:需要声明 < aop :aspectj-autoproxy />,这样将会在Spring容器中添加自动AOP代理创建bean,并处理 @Aspect注解。
<bean id="testAop" class="com.xl.AopTestClass1"/> <!-- 定义aop测试bean -->
<aop:aspectj-autoproxy />
<bean class="com.xl.PrintAspectTrace1"/><!-- 任然需要定义切面bean -->
<bean class="com.xl.PrintAspectTrace2" />

4)切面应用示例
 
 
 
 
AopTestClass1 aopTestClass = (AopTestClass1) context.getBean("aopTest");
try {
    aopTestClass.testNormalAdvice();
} catch (Exception e) {
    e.printStackTrace();
}
aopTestClass.testAroundAdvice();

aopTestClass.testNormalAdviceWithArgs("ha ~ ha !");
5)结果
around  --- before
This before_ !
 Test  normal advice!!!
around  --- after
This after_ !
This after_return_ !

This test_Around !
 Test  around advice!!!

around  --- beforeha ~ ha !com.xl.AopTestClass1@398e54e8
This before_ !ha ~ ha !com.xl.AopTestClass1@398e54e8
 Test  normal advice  with arg!!!ha ~ ha !
around  --- afterha ~ ha !com.xl.AopTestClass1@398e54e8


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值