自己实现一个spring-AOP思路

aop的加载顺序要在IOC加载的前面,即是要实例完代理类之后才在这个实例上注入属性。

 实现一个基于注解的aop:

  1、定义一个切面注解 Aspect

/**
 * 切面注解
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Aspect {

    Class  value();
}

  2、定义一个代理接口Proxy,定义一个实现这个接口的抽象类(切面代理  AspectProxy)

/**
 * 代理接口
 */
public interface Proxy {
    /**
     * 执行链式代理
     * @param proxyChain
     * @return
     * @throws Throwable
     */
    Object doProxy(ProxyChain proxyChain) throws Throwable;
}
/**
 * 切面代理
 */
public abstract class AspectProxy implements Proxy {

    private static final Logger logger = LoggerFactory.getLogger(AspectProxy.class);

    @Override
    public final Object doProxy(ProxyChain proxyChain) throws Throwable {
        Object result = null;

        Class cls = proxyChain.getTargetClass();
        Method method = proxyChain.getTargetMethod();
        Object[] params = proxyChain.getMethodParams();

        begin();
        try {
            if (intercept(cls, method, params)) {
               boolean flag = before(cls, method, params);
                if(!flag){
                   return "...";
                }
                  result = proxyChain.doProxyChain();
                after(cls, method, params, result);
            } else {
                result = proxyChain.doProxyChain();
            }
        } catch (Exception e) {
            logger.error("proxy failure", e);
            error(cls, method, params, e);
            throw e;
        } finally {
            end();
        }

        return result;
    }

    public void begin() {
    }

    public boolean intercept(Class cls, Method method, Object[] params) throws Throwable {
        return true;
    }

    public boolean before(Class cls, Method method, Object[] params) throws Throwable {
        return true;
    }

    public boolean after(Class cls, Method method, Object[] params, Object result) throws Throwable {
        return true;
    }

    public void error(Class cls, Method method, Object[] params, Throwable e) {
    }

    public void end() {
    }
}

 3、定义一个代理链ProxyChain

/**
 * 代理链
 *
 */
public class ProxyChain {

    private final Class targetClass;//目标类
    private final Object targetObject;//目标对象
    private final Method targetMethod;//目标方法
    private final MethodProxy methodProxy;//方法代理
    private final Object[] methodParams;//方法参数

    private List proxyList = new ArrayList();//代理列表
    private int proxyIndex = 0;//代理索引

    public ProxyChain(Class targetClass, Object targetObject, Method targetMethod, MethodProxy methodProxy, Object[] methodParams, List proxyList) {
        this.targetClass = targetClass;
        this.targetObject = targetObject;
        this.targetMethod = targetMethod;
        this.methodProxy = methodProxy;
        this.methodParams = methodParams;
        this.proxyList = proxyList;
    }

    public Object[] getMethodParams() {
        return methodParams;
    }

    public Class getTargetClass() {
        return targetClass;
    }

    public Method getTargetMethod() {
        return targetMethod;
    }

    public Object doProxyChain() throws Throwable {
        Object methodResult;
        if (proxyIndex < proxyList.size()) {//如果链还没调用完
            methodResult = proxyList.get(proxyIndex++).doProxy(this);//调用切面代理类,切面代理类会回调
        } else {//调用完成,执行目标对象的业务逻辑
            methodResult = methodProxy.invokeSuper(targetObject, methodParams);
        }
        return methodResult;
    }
}

 4、定义一个代理管理器 ProxyManager,该类会在项目启动的时候就被调用,用来实例化目标类

  

 * 代理管理器
 *
 */
public class ProxyManager {

    @SuppressWarnings("unchecked")
    public static  T createProxy(final Class targetClass, final List proxyList) {
        return (T) Enhancer.create(targetClass, new MethodInterceptor() {
            @Override
            public Object intercept(Object targetObject, Method targetMethod, Object[] methodParams, MethodProxy methodProxy) throws Throwable {
                return new ProxyChain(targetClass, targetObject, targetMethod, methodProxy, methodParams, proxyList).doProxyChain();//生成完整的代理链职责实例
            }
        });
    }
}

5、AOPHelper,负责项目启动时,获取需要生成代理的类,调用ProxyManager,实例化好这些类后保存实例在beans中,后续访问调用将拥有aop功能。

  

static {
    try {
        Map, Set>> proxyMap = createProxyMap();//获取AspectProxy的子类,如果子类有Aspect注解,获取注解中的值,这个值也是个注解类,根据这个注解类去获取所有含有这个注解类的类(这个是基于注解的aop的关键)
        Map, List> targetMap = createTargetMap(proxyMap);//根据上一步组装将要被代理的目标类的代理链
        for (Map.Entry, List> targetEntry : targetMap.entrySet()) {//变量每个需要被代理的类
            Class targetClass = targetEntry.getKey();
            List proxyList = targetEntry.getValue();
            System.out.println("targetClass:"+targetClass.getName());
            System.out.println("proxyList:"+proxyList.get(0).toString());
            Object proxy = ProxyManager.createProxy(targetClass, proxyList);//实例化
            BeanHelper.setBean(targetClass, proxy);//将实例化好的代理类保存到Beans中

        }
    } catch (Exception e) {
        LOGGER.error("aop failure", e);
    }
}

------------------------------------------------------至此,一个简单的aop开发完成-----------------------------------------

调用:

   

/**
 * 拦截 Controller 所有方法,这里可以做权限控制,日志记录,性能监控等等
 */
@Aspect(Controller.class)
public class ControllerAspect extends AspectProxy {

    private static final Logger LOGGER = LoggerFactory.getLogger(ControllerAspect.class);

    private long begin;

    @Override
    public boolean before(Class cls, Method method, Object[] params) throws Throwable {
        LOGGER.debug("---------- begin ControllerAspect ----------");

        if(true){
            return true;
        }
        return false;
    }

    @Override
    public boolean after(Class cls, Method method, Object[] params, Object result) throws Throwable {

        LOGGER.debug("----------- end ControllerAspect-----------");
        if(true){
            return true;
        }
        return false;
    }
}

 

你可能感兴趣的:(spring)