动态代理手动实现Spring AOP的基本功能

动态代理手动实现Spring AOP的基本功能:
这里使用内部类实现, 实际上可能使用反射实现会更好一些, 没仔细研究.

package com.frog.utils;

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

public class ProxyUtils {
    private final Class<?> clazz;

    private Method method;

    public void setMethod(String methodName, Class<?>... parameterTypes) throws Exception {
        method = clazz.getMethod(methodName, parameterTypes);
    }

    public ProxyUtils(Class<?> clazz) {
        this.clazz = clazz;
    }

    public Object getProxy(){
        return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new TempClass());
    }

    private boolean isSameMethod(Method method1, Method method2){
        if(method1.getName().equals(method2.getName())){
            if (!method1.getReturnType().equals(method2.getReturnType()))
                return false;
            Class<?>[] params1 = method1.getParameterTypes();
            Class<?>[] params2 = method2.getParameterTypes();
            if (params1.length == params2.length) {
                for (int i = 0; i < params1.length; i++) {
                    if (params1[i] != params2[i])
                        return false;
                }
                return true;
            }
        }
        return false;
    }

    private class TempClass implements InvocationHandler{
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
            if(ProxyUtils.this.method != null && !isSameMethod(ProxyUtils.this.method, method)) {
                return method.invoke(clazz.newInstance(), args);
            }
            Object result = null;
            boolean isNormal = true;
            try{
                ProceedingJoinPoint joinPoint = new ProceedingJoinPointImpl(method, args);
                if(around != null){
                    result = around.callBack(joinPoint);
                }else{
                    joinPoint.proceed();
                }
            }catch(Throwable t){
                isNormal = false;
                t.printStackTrace();
                return null;
            }finally{
                if(after != null) after.callBack();
                if(!isNormal && afterThrowing != null) afterThrowing.callBack();
            }

            if(afterReturning != null) afterReturning.callBack();
            return result;
        }

    }

    public interface ProceedingJoinPoint{
        public Object proceed() throws Throwable;
    }

    private class ProceedingJoinPointImpl implements ProceedingJoinPoint{
        private Method method;
        private Object[] args;
        public ProceedingJoinPointImpl(Method method, Object... args){
            this.method = method;
            this.args = args;
        }

        public Object proceed() throws Throwable{
            if(before != null) before.callBack();
            return method.invoke(clazz.newInstance(), args);
        }
    }

    private AroundHandler around;

    private AfterReturningHandler afterReturning;

    private AfterThrowingHandler afterThrowing;

    private BeforeHandler before;

    private AfterHandler after;

    public void setAroundAdvice(AroundHandler ah){
        around = ah;
    }

    public void setBeforeAdvice(BeforeHandler bmh){
        before = bmh;
    }

    public void setAfterThrowingAdvice(AfterThrowingHandler ath){
        afterThrowing = ath;
    }

    public void setAfterAdvice(AfterHandler amh){
        after = amh;
    }

    public void setAfterReturning(AfterReturningHandler arh){
        afterReturning = arh;
    }

    public interface AroundHandler{
        public abstract Object callBack(ProceedingJoinPoint joinPoint) throws Throwable;
    }

    public interface AfterReturningHandler{
        public abstract void callBack();
    }

    public interface AfterThrowingHandler{
        public abstract void callBack();
    }

    public interface BeforeHandler{
        public abstract void callBack();
    }

    public interface AfterHandler{
        public abstract void callBack();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值