18个类,带你手写Spring中AOP的实现原理

1.Joinpoint切点,就是方法执行的那个具体的点,抽象出一个接口:

//切点
public interface Joinpoint {
	// 切点的执行点
	Object proceed();
	// 获取切点所在的方法
	Method getMethod();
	//目标类
	Object getThis();
	//目标类执行的参数
	Object[] getArguments();
}

2.Advice通知,就是切面逻辑,抽象出一个接口

//切面逻辑,通知
public interface Advice {
	
}

3.Pointcut,可以理解为,Joinpoint的表述形式,例如1: get就是表示get方法处的这个Joinpoint
例如2: ge* 就表示所有ge开头的方法处,都可以作为Joinpoint.
这里没有具体给出实现方式,为了完善概念而已,默认对所有方法都匹配

public class Pointcut {
	
}

4.Advisor 通知器,包含了Pointcut 和Advice,抽象出一个接口

//通知器,里面含有Pointcut和Advice
public interface Advisor {
	Pointcut getPointcut();

	Advice getAdvice();
}

并提供一个默认的实现

public class DefaultPointcutAdvisor implements Advisor {

    private Pointcut pointcut;
    private Advice advice;

    public DefaultPointcutAdvisor(Advice advice, Pointcut pointcut) {
        this.pointcut = pointcut;
        this.advice = advice;
    }

    @Override
    public Pointcut getPointcut() {
        return this.pointcut;
    }

    @Override
    public Advice getAdvice() {
        return this.advice;
    }
}

5.以jdk的动态代理来说,如果需要创建一个目标类的代理对象,并执行相应的逻辑,需要目标类,目标类所实现的接口,还有通知器Advisor,所以可以把这些封装成一个对象AdvisedSupport,表示用来创建一个目标类的代理对象所需要的原材料.

//创建代理对象的载体,如目标对象,advice,ponitcut,advisor
public class AdvisedSupport {
	// 目标对象
	private Object target;
	// 代理对象实现的接口
	private List<Class<?>> interfaces = new ArrayList<>();
	private List<Advisor> advisors = new ArrayList<>();
}

6.抽象出一个工厂(或者委托)AopProxy,用来生产代理对象

//用于创建代理对象的委托
public interface AopProxy {
	//获取代理对象
	Object getProxy();
}

7.有了这些,我们就可以创建目标类的代理对象了,这里可以使用抽象工厂模式,抽象出大工厂AopProxyFactory,用来生产AopProxy

//生成 产生代理对象的工厂的工厂
public interface AopProxyFactory {
	//根据AdvisedSupport,创建AopProxy
	AopProxy createAopProxy(AdvisedSupport advisedSupport);
}

8.提供AopProxy 具体的实现类,使用jdk来创建,顺便实现InvocationHandler这个接口

//使用jdk的动态代理生成代理对象
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {
	//创建代理对象所需要的原材料
	private AdvisedSupport advisedSupport;

	public JdkDynamicAopProxy(AdvisedSupport advisedSupport) {
		this.advisedSupport = advisedSupport;
	}

	@Override
	public Object getProxy() {
		return Proxy.newProxyInstance(this.getClass().getClassLoader(), advisedSupport.getInterfaces(), this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws 
		//TODO这里的逻辑后续补上
	}
}

9.使用抽象工厂模式,创建aop的代理对象

//生成 产生代理对象的工厂的工厂
public interface AopProxyFactory {
	AopProxy createAopProxy(AdvisedSupport advisedSupport);
}

提供一个默认实现

public class DefaultAopProxyFactory implements AopProxyFactory {

	@Override
	public AopProxy createAopProxy(AdvisedSupport advisedSupport) {
		Object target = advisedSupport.getTarget();
		if (target.getClass().getInterfaces().length > 0) {
			return new JdkDynamicAopProxy(advisedSupport);
		}else{
			//cglib
			return null;
		}
		
	}
}

10.java中方法的执行,一般是一个对象调用一个方法,所以可以把方法的执行,抽象出一个接口,MethodInvocation 继承Joinpoint

public interface MethodInvocation extends Joinpoint{
}

可以补上第八步骤中TODO的部分代码

MethodInvocation invocation;
return invocation.proceed();

11,抽象出一个方法拦截器,就是通知器,所有通知的执行点,都从这个方法上走

//方法拦截,这里可以进行方法拦截
public interface MethodInterceptor extends Advice {

    Object invoke(MethodInvocation invocation);
}

12.抽象出一个前置通知,MethodBeforeAdvice

//前置通知
public interface MethodBeforeAdvice extends Advice {
	void before(Method method, Object[] args, Object target);
}

13.如果有一个前置通知,通知执行的是从MethodInterceptor 这个方法中的invoke方法中进入,所以需要将MethodBeforeAdvice 包装成MethodInterceptor,提供一个实现

public class MethodBeforeAdviceInterceptor implements MethodInterceptor {

	private MethodBeforeAdvice advice;

	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
		this.advice = advice;
	}

	@Override
	public Object invoke(MethodInvocation invocation) {
		advice.before(invocation.getMethod(), invocation.getArguments(), invocation.getThis());
		return invocation.proceed();
	}

}

14.这里需要一个能将Advice转换成MethodInterceptor的适配器AdvisorAdapter,先抽象出一个接口

//将Advice转换为MethodInterceptor
public interface AdvisorAdapter {
	MethodInterceptor getInterceptor(Advisor advisor);
}

并提供一个能将MethodBeforeAdvice转换成MethodInterceptor的一个实现

public class MethodBeforeAdviceAdapter implements AdvisorAdapter {
    @Override
    public MethodInterceptor getInterceptor(Advisor advisor) {
        MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
        return new MethodBeforeAdviceInterceptor(advice);
    }
}

15,这里补全所有的AdvisedSupport的支持,

//创建代理对象的载体,如目标对象,advice,ponitcut,advisor
public class AdvisedSupport {
	// 目标对象
	private Object target;

	// 代理对象实现的接口
	private List<Class<?>> interfaces = new ArrayList<>();
	private List<Advisor> advisors = new ArrayList<>();

	//默认的适配器,advice适配成MethodInterceptor
	private AdvisorAdapter advisorAdapter = new MethodBeforeAdviceAdapter();

	public Object getTarget() {
		return target;
	}

	public void setTarget(Object target) {
		this.target = target;
	}

	// 添加目标对象对象所实现的接口
	public void addInterface(Class<?>... interfaces) {
		this.interfaces.clear();
		for (Class<?> ifc : interfaces) {
			this.interfaces.add(ifc);
		}
	}

	public Class<?>[] getInterfaces() {
		return interfaces.toArray(new Class<?>[0]);
	}

	public void setInterfaces(List<Class<?>> interfaces) {
		this.interfaces = interfaces;
	}

	public List<Advisor> getAdvisors() {
		return advisors;
	}

	public void setAdvisors(List<Advisor> advisors) {
		this.advisors = advisors;
	}

	//根据advisor,获取到advice,并将advice,适配成所有的MethodInterceptor
	public List<Object> getInterceptorsAndDynamicInterceptionAdvice() {
		List<Object> interceptorList = new ArrayList<>();
		for (Advisor advisor : this.advisors) {
			if (advisor instanceof DefaultPointcutAdvisor) {
				interceptorList.add(advisorAdapter.getInterceptor(advisor));
			}
		}
		return interceptorList;
	}

	//如果添加的是一个advice,封装成一个Advisor,并加入链表
	public void addAdvice(Advice advice) {
		addAdvisor(new DefaultPointcutAdvisor(advice, null));
	}

	public void addAdvisor(Advisor advisor) {
		this.advisors.add(advisor);
	}
}

16.因为生产的代理对象之后,执行方法,都是从JdkDynamicAopProxy中invoke中的方法进入,这里我有转换成从MethodInvocation的proceed()方法进入,所以这里提供一个MethodInvocation的实现,用来处理方法的通知,和调用,

//处理切面逻辑的地方
public class ReflectiveMethodInvocation implements MethodInvocation {
	// 代理对象
	private Object proxy;
	// 目标对象
	private Object target;
	// 目标方法
	private Method method;
	// 一连串的通知器,都封装成MethodInterceptor
	protected final List<?> interceptorsAndDynamicMethodMatchers;

	private Object[] aguments;

	// 代表执行到第几个通知器链
	private int currentInterceptorIndex = -1;

	public ReflectiveMethodInvocation(Object proxy, Object target, Method method, Object[] aguments,
			List<Object> interceptorsAndDynamicMethodMatchers) {
		this.proxy = proxy;
		this.target = target;
		this.method = method;
		this.aguments = aguments;
		this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
	}

	@Override
	public Object proceed() {

		if (this.currentInterceptorIndex == interceptorsAndDynamicMethodMatchers.size() - 1) {
			try {
				//目标方法的最终调用
				return method.invoke(target, aguments);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		//这里就是将advice封装成MethodInterceptor.从链表中一个一个执行
		Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers
				.get(++this.currentInterceptorIndex);
		//这里将ReflectiveMethodInvocation自己用传入了,所以是一个递归调用
		return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
	}

	@Override
	public Method getMethod() {
		return method;
	}

	@Override
	public Object getThis() {
		return target;
	}

	@Override
	public Object[] getArguments() {
		return aguments;
	}
}

17.完善第八步骤中的invoke方法,

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		MethodInvocation invocation;
		// 获取到所有的调用器链
		List<Object> chain = this.advisedSupport.getInterceptorsAndDynamicInterceptionAdvice();
		invocation = new ReflectiveMethodInvocation(proxy, advisedSupport.getTarget(), method, args, chain);
		return invocation.proceed();
	}
}

到这里,spring中aop的核心实现就是这样,然后结合spring中的Factorybean,或者BeanPostProcessor.就完成spring中aop功能的实现

测试类:

public class Test01 {

    public static void main(String[] args) {
        IA ia = new AImpl();
        ProxyFactory proxyFactory = new ProxyFactory(ia);
        proxyFactory.addInterface(IA.class);
        proxyFactory.addAdvice(new MethodBeforeAdvice() {
            @Override
            public void before(Method method, Object[] args, Object target) {
                System.out.println("1-----------------");
            }
        });
        proxyFactory.addAdvice(new MethodBeforeAdvice() {
            @Override
            public void before(Method method, Object[] args, Object target) {
                System.out.println("2----------------");
            }
        });
        IA proxyObj = (IA) proxyFactory.getProxy();
        proxyObj.ext();

    }
}

interface IA{
    void ext();
}

class AImpl implements IA{
    @Override
    public void ext() {
        System.out.println("--------------");
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值