0%

Adapter

介绍

AOP中,使用 Advice(通知)来实现被代理类的功能,使用代理模式,代理类在方法中通过执行拦截器,实现面向切面编程。

举个例子 前置处理 备注:源代码中省去了一些代码

public interface Advice {

}
public interface BeforeAdvice extends Advice {

}
public interface Advisor {
Advice getAdvice();
}
public interface MethodBeforeAdvice extends BeforeAdvice {
void before(Method method, Object[] args, @Nullable Object target) throws Throwable;
}

实现Advisor接口的子类适配,获取 Advice 通知

class MethodBeforeAdviceAdapter implements AdvisorAdapter {

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

}

通过 MethodBeforeAdviceInterceptor 类 ,调用了 before 方法,实现方法前拦截

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}

}

查看源代码before最终调用的是 Method 类的 invoke 方法

public Object invoke(Object obj, Object... args)
{
MethodAccessor ma = methodAccessor;
return ma.invoke(obj, args);
}

通知通过代码如何实现AOP

举例 spring AOP JDK 动态代理方式的实现

  • 配置 MethodBeforeAdvice 的实现类
  • JDK通过实现接口的方式实现动态代理,那么定义一个接口
  • 编写接口实现类
  • 配置代理类,通过 ProxyFactoryBean 生成需要的
    • 拦截器(这里举例的是前置通知 MethodBeforeAdvice 的实现类)
    • 代理接口(JDK通过实现接口的方式实现动态代理,定义的接口)
    • 目标对象(接口实现类)
public class ProxyFactoryBean extends ProxyCreatorSupport
implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {

public void setInterceptorNames(String... interceptorNames) {
super.setInterceptorNames(interceptorNames);
}

//没有设置目标对象的代理接口,则使用CGLIB创建代理
public void setProxyInterfaces(Class<?>[] proxyInterfaces) throws ClassNotFoundException {
super.setProxyInterfaces(proxyInterfaces);
}
public void setTargetName(String targetName) {
super.setTargetName(targetName);
}
}