面向切面编程:AOP   (对动态代理的封装)(底层是反射和动态代理) 
 

 1.开发步骤: 
 
   1.导入包:spring-aop (3.2.8)  aspectjweaver(1.8.0)   aspectjtools(1.8.0) 
 
   2.开发aop bean 组件 : 
 
    类注解:@component 
 
      @Aspect  
 
    方法注解:@Before  方法执行前(是sapectj的注解,不是junit的) 
 
        @After    方法执行后 
 
   3.配置xml   
 
    1.配置包扫描:<context:component-scan base-package="类的全路径"/> 
 
    2.配置注解生效:<aop:aspectj-autoproxy/> 
 

    
 
   
 
 2.通知:声明AOP方法在目标业务层的执行位置 
 
  常用的通知有5种: 
 
  @Before   在目标方法执行之前执行 
 
  @After    在目标方法执行之后执行,无论目标业务方法是否出现异常@After修饰的方法都会执行 
 
  @AfterThrowing    在目标方法执行发生异常之后,会执行@AfterThrowing修饰的方法 
 
  @AfterReturning   在目标方法正常执行之后,如果没有异常发生,则执行@AfterReturning修饰的方法 
 
  @Around     万能通知,可以替代其他几个通知,但是使用繁琐 
 
   
 
   
 
  执行方法顺序小节: 
 
  代理执行 
 
  try{ 
 
   @Before        //----------(1) 
 
   反射执行目标方法 
 
   @AfterReturning   //--------(2) 
 
  }finally{ 
 
   @After            //-------(3) 
 
  }catch(){ 
 
      //@AfterReturning修饰的方法执行在@After之后,并且是执行方法时发生了异常!!! 
 
   @AfterThrowing     //---------(4) 
 
  } 
 
 
 
  @Around("bean(userService)")   
 
  1.必须有参数ProceedingJoinPoint   。。。代理连接点 
 
  2.必须有返回值 Object 
 
  3.必须抛出异常 
 
  例:测试业务层的性能 
 
  @Around("bean(userService)") 
 
  public Object testAround(ProceedingJoinPoint pjp) throws Throwable{ 
 
   try{ 
 
    long t1 = System.currentTimeMilles(); 
 
    Object obj = pjp.proceed();   //代理连接点继续执行方法,抛出异常 
 
    logn t2 = System.currentTimeMilles(); 
 
    Signature n = pjp.getSignature();    //获取方法的签名(Signature导入的包是 org.aspectj.lang.Signature) 
 
    System.out.println((t2-t1)+":"+n);    //输出执行的方法以及执行所用的时间 
 
    return obj;    //返回执行结果 
 
   }catch(Throwble e){ 
 
    throw e; 
 
   } 
 
  } 
 
 3.切入点表达式:(bean组件切入点) 
 
  语法: 
 

      @Before("bean(suerService)") //切入到userService的全部方法 
 
     @Before("bean(userService) || bean(cartService)")  //将两个用或连接,切入两个业务接口 
 
     @Before("bean(*Service)") //切入到Service的全部方法 
 
     @Before("within(cn.tedu.store.userServiceImpl)")  //等同于  @Before("bean(userService)") 
 
    
 
     //切入类 UserServiceImplement 中声明的全部方法 
 
     @Before("within(cn.tedu.store.service.UserServiceImpl)") 
 
     @Before("within(cn.tedu.store.service.*ServiceImpl)") 
 
     @Before("within(cn.tedu.store.service..*)") 
 
     
 
     
 
     //切入方法,方法名要通用,规范 
 
     @Before("execution(修饰词 类名.方法名(参数类型))") 
 
     @Before("execution(* cn.tedu.store.service.UserService.login(..))") 
 
     @Before("execution(* cn.tedu.store..*Service.login(..))") 
 
  备注:..表示省略,*表示包名 
 
     
 
 4.AOP的工作原理: 
 
  SpringAOP 底层是Aspectj,再底层是利用了java的反射和动态代理。 
 
  其中反射用于解析注解,动态代理用于生成代理对象。 
 
   
 
  SpringAOP的底层代理方式有两种,一种是基于java动态代理,一种是基于CGLIB的动态代理。 
 
  当被代理对象有接口时候优先使用java动态代理,如果被代理对象没有接口的时候,会自动使用 
 
  CGLIB。一般情况下都推荐使用java动态代理,毕竟是官方的,比较可靠。