• 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

  • 相关阅读:
    python编码小记
    eventlet学习笔记
    python库文件路径
    paste deploy初探
    python浅拷贝与深拷贝
    Javascript basic knowledge
    用大数据学习心理学
    Postgres Database management operations
    Python Socket and WSGI Sample
    Failed to connect socket to '/var/run/libvirt/libvirt-sock': No such file or directory错误处理
  • 原文地址:https://www.cnblogs.com/li-yan-long/p/15191619.html
Copyright © 2020-2023  润新知