简单学习---AOP实现原理

Spring里最重要的两个特性就当属IOC和AOP吧,对于AOP的原理最近看书自我感觉理解了不少,在此还是做个笔记记录一下,不要只有嘴上功夫。

直接通过一个例子来说明吧,本人组织能力不太行,从别人那复制粘贴过来也没啥意思,懂的都懂,感觉没啥必要哈哈哈哈哈哈哈哈

  1. 先创建一个简单的接口和它的实现类
//使用的是JDK自带的方法生成代理对象实现切面的效果,因此接口是不能少的,不用接口的那个CGLIB,那个以后看看吧
public interface HelloService {
    void hello(String name);
}

public class HelloServiceImpl implements HelloService {
    @Override
    public void hello(String name) {
        //加了个抛异常方便后面模拟出异常的调用的切面方法
        if (StringUtils.isEmpty(name)) {
            throw new RuntimeException("name is null!");
        }
        System.out.println("hello "+name);
    }
}
  1. 定义Invocation类,它用是于实现环绕通知功能的一个类,主要就是通过反射进行作用
public class Invocation {
    private Object[] params;
    private Method method;
    private Object target;

    public Invocation(Object[] params, Method method, Object target) {
        this.params = params;
        this.method = method;
        this.target = target;
    }

    //getset方法省略
}
  1. 定义拦截器接口以及实现类
public interface Interpector {

    boolean before();

    void after();

    Object around(Invocation invocation);

    void afterReturning();

    void afterThrowing();

    boolean useAround();
}

public class MyInterceptor implements Interpector{
    @Override
    public boolean before() {
        System.out.println("before..............");
        return true;
    }

    @Override
    public void after() {
        System.out.println("after...............");
    }

    @Override
    public Object around(Invocation invocation) throws InvocationTargetException, IllegalAccessException {
        System.out.println("around before.......");
        Object obj = invocation.proceed();
        System.out.println("around after........");
        return obj;
    }

    @Override
    public void afterReturning() {
        System.out.println("after returning.....");
    }

    @Override
    public void afterThrowing() {
        System.out.println("after throwing......");
    }

    @Override
    public boolean useAround() {
        return true;
    }
}
  1. 生成代理对象的工具类
//注意这个实现了JDK自带的InvocationHandler接口
public class ProxyCreator implements InvocationHandler {
    private Object target;
    private Interceptor interceptor;
    //在下面这个重写的方法里写好具体切面怎么切
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        boolean exceptionFlag = false;
        Invocation invocation = new Invocation(target, method, args);
        interceptor.before();
        Object returnObj = null;
        try {
            if (interceptor.useAround()) {
                returnObj = interceptor.around(invocation);
            } else {
                returnObj = method.invoke(target, args);
            }
        } catch (Exception e) {
            exceptionFlag = true;
        }
        interceptor.after();
        if (exceptionFlag) {
            interceptor.afterThrowing();
        }else {
            interceptor.afterReturning();
            return returnObj;
        }
        return null;
    }

    public static Object getProxyBean(Object target, Interceptor interceptor) {
        ProxyCreator proxyCreator = new ProxyCreator();
        proxyCreator.target = target;
        proxyCreator.interceptor = interceptor;
        //JDK自带的静态方法,用它可以生成代理对象,三个参数为:类加载器、绑定的接口,实现了InvocationHandler接口的一个类的对象
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), proxyCreator);
    }
}
  1. 简单写一个测试类测试一下
public class AOPTest {
    HelloService helloService;
    @Before
    public void getProxyObj(){
        helloService = (HelloService) ProxyCreator.getProxyBean(new HelloServiceImpl(), new MyInterceptor());
    }
    @Test
    public void test_name_is_not_null(){
        helloService.hello("world");
    }
    @Test
    public void test_name_is_null(){
        //null或者空字符串都可以
        helloService.hello(null);
    }
}

结果如下

#test_name_is_not_null
before..............
around before.......
hello world
around after........
after...............
after returning.....
#test_name_is_null
before..............
around before.......
after...............
after throwing......
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值