Spring面向切面编程初探

定义AOP术语

通知

通知定义了切面是什么以及何时使用切面。Spring切面可以应用5种类型的通知:

  1. Before: 在方法被调用之前通知
  2. After: 在方法完成之后调用通知,无论方法是否执行成功
  3. After-returning: 在方法成功执行之后调用通知
  4. After-throwing: 在方法抛出异常之后调用通知
  5. Around: 通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义行为

连接点

连接点是在应用执行过程中 能够插入切面的一个点,这个点可以是调用方法时,抛出异常时,甚至是修改一个字段时。切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。

切点

切点即为切面切入的 位置

引入

引入允许我们向现有的类添加新的方法和属性,目的是在无需修改现有类的情况下,让他们具有新的行为和状态。

织入

织入是将切面应用到目标对象来创建新的代理对象的 过程

在XML中声明切面

非环绕型通知





 
   
     
       
         
         
         

        
         
        
        

         
         
         
         
         
         

     
 

简单测试一下:

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person tom = (Person) ctx.getBean("tom");
        tom.sayHello();

环绕型通知


        
            
            
            
        

我们来看一下JavaBean中是如何声明这个方法的:

//AOP环绕通知
public void watchYouSayHello(ProceedingJoinPoint joinPoint) {

    try {
        System.out.println("Before say hello!");

        long start = System.currentTimeMillis();

        //执行被通知的方法
        joinPoint.proceed();

        long end = System.currentTimeMillis();

        System.out.println("Say hello finished!");
        System.out.println("This project has run " + (end - start) + "ms!");


    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }
}

在main方法中执行后效果同上。

注解切面

非环绕型通知

注解切面可以使我们免于在XML中配置AOP

@Aspect
public class Robot {
  //声明切点
    @Pointcut("execution(* entity.Person.sayHello(..))")
    //声明切点标识方法
    public void sayHello() {

    }
    //通知前置调用
    @Before("sayHello()")
    public void beforeSayHello() {
        System.out.println("before say hello");
    }
    //通知后置调用
    @After("sayHello()")
    public void afterSayHello() {
        System.out.println("after say hello");
    }
    //方法执行成功后调用
    @AfterReturning("sayHello()")
    public void finishSayHello() {
        System.out.println("say hello finished");
    }
    //方法执行异常时调用
    @AfterThrowing("sayHello()")
    public void exceptionThrows() {
        System.out.println("an exception was throwed");
    }

    //AOP环绕通知
    @Around("sayHello()")
    public void watchYouSayHello(ProceedingJoinPoint joinPoint) {

        try {
            System.out.println("before say hello");

            long start = System.currentTimeMillis();

            //执行被通知的方法
            joinPoint.proceed();

            long end = System.currentTimeMillis();

            System.out.println("say hello finished");
            System.out.println("this project has run " + (end - start) + "ms");


        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}

但是我们需要在XML中的beans根标签下额外配置一些东西



    
    

    
    


环绕型通知

@Aspect
public class Robot {
    @Pointcut("execution(* entity.Person.sayHello(..))")
    public void sayHello() {

    }

    //AOP环绕通知
    @Around("sayHello()")
    public void watchYouSayHello(ProceedingJoinPoint joinPoint) {

        try {
            System.out.println("before say hello");

            long start = System.currentTimeMillis();

            //执行被通知的方法
            joinPoint.proceed();

            long end = System.currentTimeMillis();

            System.out.println("say hello finished");
            System.out.println("this project has run " + (end - start) + "ms");


        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}

你可能感兴趣的:(Spring面向切面编程初探)