spring aop

AOP面向切面编程:由动态代理的方式去执行业务类方法。将业务类以参数的形式传入代理类,然后代理类返回一个业务类的对象。此时返回的对象不管执行什么方法,都会直接去执行代理类的invoke方法。一般实现在invoke方法中去调用该业务类的方法。从而达到面向切面编程(方法前方法后都会有方法执行)。

1.业务类

package com.mr.li.test.aop;

public interface HelloService {

    void sayHello(String name);
}

 

package com.mr.li.test.aop;

public class HelloServiceImpl implements HelloService {

    @Override
    public void sayHello(String name) {
        if(name == null || name.trim() == "") {
            throw new RuntimeException("参数为null");
        }
        System.out.println("hello " + name);
    }

}

 

2.过滤器(自己写的,用于在方法前方法后执行,将其传入到代理类中然后在invoke方法中编辑执行)

package com.mr.li.test.aop;

import java.lang.reflect.InvocationTargetException;

/**
 * 
 * @describe 拦截器
 *
 * @author li.yanlong@icjhd.com
 *
 * @date 2021-8-26 11:47:33
 */
public interface Interceptor {

    /** 方法前执行的方法 */
    boolean before();
    
    /** 方法后执行的方法 */
    void after();

    /** 取代原有事件方法, 通过invocation回调参数,可以通过他的proceed方法回调原事件 */
    Object around(Invocation invocation) throws InvocationTargetException, IllegalAccessException;

    /** 是否返回方法,事件没有发生异常执行 */
    void afterReturning();
    
    /** 事后异常方法,当事件发生异常后执行 */
    void afterThrowing();
    
    /** 是否使用around方法取代原有方法 */
    boolean useAround();
}

 

package com.mr.li.test.aop;

import java.lang.reflect.InvocationTargetException;

public class MyInterceptor implements Interceptor {

    @Override
    public boolean before() {
        System.out.println("方法执行前执行~~~before");
        return false;
    }

    @Override
    public void after() {
        System.out.println("方法执行后执行~~~~after");
    }

    @Override
    public Object around(Invocation invocation) throws InvocationTargetException, IllegalAccessException {
        System.out.println("代理方法执行~~~~around");
        Object obj = invocation.proceed();
        return obj;
    }

    @Override
    public void afterReturning() {
        System.out.println("方法没有发生异常时正常执行~~~~~~afterReturning");
    }

    @Override
    public void afterThrowing() {
        System.out.println("当方法发生异常时执行~~~~~~~afterThrowing");
    }

    @Override
    public boolean useAround() {
        System.out.println("是否使用around方法取代原有方法 执行~~~~~useAround 返回true");
        return true;
    }

}

 

3.代理类的参数对象

package com.mr.li.test.aop;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 
 * @describe 代理对象执行方法
 *
 * @author li.yanlong@icjhd.com
 *
 * @date 2021-8-26 18:28:59
 */
public class Invocation {

    private Object[] parame;
    
    private Method method;
    
    private Object target;

    public Invocation(Object[] parame, Method method, Object target) {
        this.parame = parame;
        this.method = method;
        this.target = target;
    }
    
    //以反射的方式调用方法
    public Object proceed() throws InvocationTargetException, IllegalAccessException{
        return method.invoke(target, parame);//target调用该方法的对象, parame:调用该方法的参数
    }
}

 

4.代理类:表示将业务类传进来,然后返回一个对象,该对象就是业务类的对象,然后该对象在转成具体的对象,此时只要执行该对象的方法,就会执行代理类的invoke,

package com.mr.li.test.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyBean implements InvocationHandler {

    private Object target = null;
    
    private Interceptor interceptor = null;
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        boolean exceptionFlag = false;
        Invocation invocation = new Invocation(args, method, target);
        Object retObj = null;
        try {
            if(this.interceptor.before()) {
                retObj = this.interceptor.around(invocation);
            }else {
                retObj = method.invoke(target, args);
            }
        } catch (Exception e) {
            exceptionFlag = true;
        }
        this.interceptor.after();
        if(exceptionFlag) {
            this.interceptor.afterThrowing();
        }else {
            this.interceptor.afterReturning();
            return retObj;
        }    
        return null;
    }

    public static Object getProxyBean(Object target, Interceptor interceptor) {
        ProxyBean proxyBean = new ProxyBean();
        proxyBean.target = target;
        proxyBean.interceptor = interceptor;
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), proxyBean);
        return proxy;
    }
}

 

5.测试

package com.mr.li.test.aop;

public class Test {

    public static void main(String[] args) {
        HelloService helloService = new HelloServiceImpl();
        HelloService proxy = (HelloService)ProxyBean.getProxyBean(helloService, new MyInterceptor());
        proxy.sayHello("哈哈哈");
        
        System.out.println("------------------------------------------------");
        proxy.sayHello(null);
    }
}

测试结果:

方法执行前执行~~~before
hello 哈哈哈
方法执行后执行~~~~after
方法没有发生异常时正常执行~~~~~~afterReturning
------------------------------------------------
方法执行前执行~~~before
方法执行后执行~~~~after
当方法发生异常时执行~~~~~~~afterThrowing

posted @ 2021-08-26 21:34  ~~mr.li~~  阅读(33)  评论(0)    收藏  举报