30--基于Schema的AOP

前几篇已经对AOP中的相关概念做了解释,但是都是通过编码方式实现的,每次都需要通过ProxyFactory去创建代理,接下来我们介绍Spring中的自动代理方式来实现AOP,基于Schema配置文件方式和基于@AspectJ注解的方式。当然自动代理实现的机制,放到后面的章节分析,本篇权当温习,也为接下来的源码分析做好铺垫。

1.普通切面
  • 目标对象
package com.lyc.cn.v2.day06;

public interface Animal {
    void sayHello(String name,int age);

    void sayException(String name, int age);
}
package com.lyc.cn.v2.day06;

public class Cat implements Animal {

    @Override
    public void sayHello(String name, int age) {
        System.out.println("--调用被增强方法");
    }

    @Override
    public void sayException(String name, int age) {
        System.out.println("==抛出异常:" + 1 / 0);
    }
}
  • 切面类
package com.lyc.cn.v2.day06;

import org.aspectj.lang.ProceedingJoinPoint;

public class CatAspect {

    /**
     * 前置增强
     */
    public void beforeAdvice(String name, int age) {
        System.out.println("==前置增强,name:" + name + ",age:" + age);
    }

    /**
     * 后置异常增强
     */
    public void afterExceptionAdvice(String name, int age) {
        System.out.println("==后置异常增强,name:" + name + ",age:" + age);
    }

    /**
     * 后置返回增强
     */
    public void afterReturningAdvice(String name, int age) {
        System.out.println("==后置返回增强,name:" + name + ",age:" + age);
    }

    /**
     * 后置最终增强
     */
    public void afterAdvice(String name, int age) {
        System.out.println("==后置最终增强,name:" + name + ",age:" + age);
    }

    /**
     * 环绕增强
     */
    public Object roundAdvice(ProceedingJoinPoint p, String name, int age) {
        System.out.println("==环绕增强开始,name:" + name + ",age:" + age);
        Object o = null;
        try {
            o = p.proceed();
            Object[] args = p.getArgs();
            if (null != args) {
                for (int i = 0; i < args.length; i++) {
                    System.out.println("==环绕增强参数值:" + args[i]);
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("==环绕增强结束,name:" + name + ",age:" + age);
        return o;
    }

}
  • 配置文件



    
    

    
    

    
    
        
        
        
            
            
            
            
            
            
            
            
            
            
        
    

  • 测试类及结果
package com.lyc.cn.v2.day06;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {

    @Test
    public void test1() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("v2/day06.xml");
        Cat cat = ctx.getBean("cat", Cat.class);
        cat.sayHello("美美", 3);
    }


    @Test
    public void test2() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("v2/day06.xml");
        Cat cat = ctx.getBean("cat", Cat.class);
        cat.sayException("美美", 3);
    }
}
// 测试1
==前置增强,name:美美,age:3
==环绕增强开始,name:美美,age:3
--调用被增强方法
==环绕增强参数值:美美
==环绕增强参数值:3
==环绕增强结束,name:美美,age:3
==后置最终增强,name:美美,age:3
==后置返回增强,name:美美,age:3
// 测试2
==前置增强,name:美美,age:3
==环绕增强开始,name:美美,age:3

==环绕增强结束,name:美美,age:3
==后置最终增强,name:美美,age:3
==后置返回增强,name:美美,age:3java.lang.ArithmeticException: / by zero
    at com.lyc.cn.v2.day06.Cat.sayException(Cat.java:12)
    at com.lyc.cn.v2.day06.Cat$$FastClassBySpringCGLIB$$336350b6.invoke(

相信大家对这样的配置已经非常熟悉了,而且在配置文件中已经有了比较完善的说明,而且Schema的配置方式已经不是那么流行,所以我们不做过多的介绍。

2.引介增强

Spring引入允许为目标类对象引入新的接口。

  • 引介接口和实现
package com.lyc.cn.v2.day06;

/**
 * 引入
 * @author: LiYanChao
 * @create: 2018-10-28 15:48
 */
public interface IIntroduce {
    void sayIntroduce();
}
package com.lyc.cn.v2.day06;

/**
 * @author: LiYanChao
 * @create: 2018-10-28 15:48
 */
public class IntroduceImpl implements IIntroduce {
    @Override
    public void sayIntroduce() {
        System.out.println("--引入");
    }
}
  • 修改配置文件配置引介增强
    标签中加入如下配置:


  • 测试及结果
@Test
public void test3() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("v2/day06.xml");
    // 注意:getBean获取的是cat
    IIntroduce introduce = ctx.getBean("cat", IIntroduce.class);
    introduce.sayIntroduce();
}
--引入
3.总结

本篇主要回顾一下基于Schema的AOP的配置方式,都是基于配置文件,当然这里涉及到的知识点也很多,这里只是做了简单的介绍,关于更多的配置,大家可以参考Spring的官方文档。

你可能感兴趣的:(30--基于Schema的AOP)