第二章 AOP

AOP

  • JDK的实现
  • Clib的实现
源码设计

AdvisedSupport …

@Data
public class AdvisedSupport {

  private TargetSource targetSource;

  private MethodInterceptor methodInterceptor;

  private MethodMatcher methodMatcher;
}

TargetSource …

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class TargetSource {

  //目标代理的实现类
  private Class<?> targetClass;

  //目标代理类的接口
  private Class<?>[] interfaces;

  //目标对象
  private Object target;

  public TargetSource(Object target, Class<?> targetClass,Class<?>... interfaces) {
    this.target = target;
    this.targetClass = targetClass;
    this.interfaces = interfaces;
  }

}

拦截器

public class TimerInterceptor implements MethodInterceptor {
  @Override
  public Object invoke(MethodInvocation invocation) throws Throwable {
    long time = System.nanoTime();
    System.out.println("Invocation of Method " + invocation.getMethod().getName() + " start!");
    Object proceed = invocation.proceed();
    System.out.println("Invocation of Method " + invocation.getMethod().getName() + " end! takes " + (System.nanoTime() - time)
        + " nanoseconds.");
    return proceed;
  }
}

顶层获取代理类对象

public interface AopProxy {
  Object getProxy();
}
public abstract class AbstractAopProxy implements AopProxy {

  protected AdvisedSupport advised;

  public AbstractAopProxy(AdvisedSupport advised) {
    this.advised = advised;
  }
}

public class JdkDynamicAopProxy extends  AbstractAopProxy implements InvocationHandler {

  public JdkDynamicAopProxy(AdvisedSupport advised) {
    super(advised);
  }

  @Override
  public Object getProxy() {
    return Proxy.newProxyInstance(getClass().getClassLoader(), advised.getTargetSource().getInterfaces(), this);
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    MethodInterceptor methodInterceptor = advised.getMethodInterceptor();
    if (advised.getMethodMatcher() != null &&
      //
      advised.getMethodMatcher().matches(method, advised.getTargetSource().getClass())) {
      return methodInterceptor.invoke(new ReflectiveMethodInvocation(advised.getTargetSource().getTarget(),
          method, args));
    } else {
      // 反射调用执行目标实现类的方法
//      return methodInterceptor.invoke(new ReflectiveMethodInvocation(advised.getTargetSource().getTarget(),
//          method, args));
       return method.invoke(advised.getTargetSource().getTarget(), args);
    }
  }
}
public class JdkDynamicAopProxyTest {

  @Test
  public void testInterceptor() throws Exception {
    // --------- helloWorldService without AOP
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("tinyioc.xml");
    CatDemo cat = (CatDemo)applicationContext.getBean("cat");;
     System.out.println(cat.getCat());
    // 1. 设置被代理对象(Joinpoint)
    AdvisedSupport advisedSupport = new AdvisedSupport();
    TargetSource targetSource = new TargetSource(cat, CatDemoImpl.class,
        CatDemo.class);
    advisedSupport.setTargetSource(targetSource);
    // 2. 设置拦截器(Advice)
    TimerInterceptor timerInterceptor = new TimerInterceptor();
    advisedSupport.setMethodInterceptor(timerInterceptor);
    // 3. 创建代理(Proxy)
    JdkDynamicAopProxy jdkDynamicAopProxy = new JdkDynamicAopProxy(advisedSupport);
    CatDemo helloWorldServiceProxy = (CatDemo) jdkDynamicAopProxy.getProxy();
    // 4. 基于AOP的调用
    helloWorldServiceProxy.getCat();

  }

如何与spring定义的IOC接口实现自动配置

  <bean id="autoProxyCreator" class="com.cn.spring.aop.AspectJAwareAdvisorAutoProxyCreator"></bean>

  <bean id="child" class="com.cn.spring.bean.ChildDemo"></bean>

  <bean id = "cat" class="com.cn.spring.bean.CatDemoImpl"></bean>

  <bean id="timerInterceptor" class="com.cn.spring.aop.TimerInterceptor"></bean>

  <bean id="aspectjAspect" class="com.cn.spring.aop.AspectJExpressionPointcutAdvisor">
    <property name="advice" ref="timerInterceptor"></property>
    <property name="expression" value="execution(* com.cn.spring.bean.*.*(..))"></property>
  </bean>

获取bean工厂

public interface BeanFactoryAware {

  void setBeanFactory(BeanFactory beanFactory) throws Exception;
}

实现自动装配类

public interface BeanPostProcessor {

  Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception;

  Object postProcessAfterInitialization(Object bean, String beanName) throws Exception;
}
public class AspectJAwareAdvisorAutoProxyCreator implements BeanPostProcessor, BeanFactoryAware {

  private AbstractBeanFactory beanFactory;
  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws Exception {
    this.beanFactory = (AbstractBeanFactory) beanFactory;
  }

  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception {
    return bean;
  }

  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws Exception {
    if (bean instanceof AspectJExpressionPointcutAdvisor) {
      return bean;
    }
    if (bean instanceof MethodInterceptor) {
      return bean;
    }
    List<AspectJExpressionPointcutAdvisor> advisors = beanFactory
        .getBeansForType(AspectJExpressionPointcutAdvisor.class);
    for (AspectJExpressionPointcutAdvisor advisor : advisors) {
      if (advisor.getPointcut().getClassFilter().matches(bean.getClass())) {
        ProxyFactory advisedSupport = new ProxyFactory();
        advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice());
        advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatch());
        TargetSource targetSource = new TargetSource(bean, bean.getClass(), bean.getClass().getInterfaces());
        advisedSupport.setTargetSource(targetSource);
        return advisedSupport.getProxy();
      }
    }
    return bean;
  }
}

public interface Advisor {

  Advice getAdvice();
}
public interface PointcutAdvisor extends Advisor{

  Pointcut getPointcut();
}

public class AspectJExpressionPointcutAdvisor implements PointcutAdvisor {

  private AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();

  private Advice advice;

  public void setAdvice(Advice advice) {
    this.advice = advice;
  }

  public void setExpression(String expression) {
    this.pointcut.setExpression(expression);
  }

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

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

这里为什么这么封装、是因为每个类对外方法使用。

public interface Pointcut {

  ClassFilter getClassFilter();

  MethodMatcher getMethodMatch();

}

public interface ClassFilter {

  boolean matches(Class targetClass);
}

public interface MethodMatcher {

  boolean matches(Method method, Class targetClass);
}

public class AspectJExpressionPointcut implements Pointcut, ClassFilter, MethodMatcher {

  private PointcutParser pointcutParser;

  private String expression;

  private PointcutExpression pointcutExpression;

  private static final Set<PointcutPrimitive> DEFAULT_SUPPORTED_PRIMITIVES = new HashSet<PointcutPrimitive>();

  static {
    DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION);
    DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.ARGS);
    DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.REFERENCE);
    DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.THIS);
    DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.TARGET);
    DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.WITHIN);
    DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ANNOTATION);
    DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_WITHIN);
    DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ARGS);
    DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_TARGET);
  }

  public AspectJExpressionPointcut() {
    this(DEFAULT_SUPPORTED_PRIMITIVES);
  }

  public AspectJExpressionPointcut(Set<PointcutPrimitive> supportedPrimitives) {
    pointcutParser = PointcutParser
        .getPointcutParserSupportingSpecifiedPrimitivesAndUsingContextClassloaderForResolution(supportedPrimitives);
  }

  protected void checkReadyToMatch() {
    if (pointcutExpression == null) {
      pointcutExpression = buildPointcutExpression();
    }
  }

  private PointcutExpression buildPointcutExpression() {
    return pointcutParser.parsePointcutExpression(expression);
  }

  public void setExpression(String expression) {
    this.expression = expression;
  }


  @Override
  public boolean matches(Class targetClass) {
    checkReadyToMatch();
    return pointcutExpression.couldMatchJoinPointsInType(targetClass);
  }

  @Override
  public boolean matches(Method method, Class targetClass) {
    // 检查表达式是否正常
    checkReadyToMatch();
    ShadowMatch shadowMatch = pointcutExpression.matchesMethodExecution(method);
    if (shadowMatch.alwaysMatches()) {
      return true;
    } else if (shadowMatch.neverMatches()) {
      return false;
    }
    return false;
  }

  @Override
  public ClassFilter getClassFilter() {
    return this;
  }

  @Override
  public MethodMatcher getMethodMatch() {
    return this;
  }
}
public class ProxyFactory extends AdvisedSupport implements AopProxy {
  @Override
  public Object getProxy() {
    return createAopProxy().getProxy();
  }

  protected final AopProxy createAopProxy() {
    return new Cglib2AopProxy(this);
  }
}

public class Cglib2AopProxy extends AbstractAopProxy {
  public Cglib2AopProxy(AdvisedSupport advised) {
    super(advised);
  }

  @Override
  public Object getProxy() {
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(advised.getTargetSource().getTargetClass());
    enhancer.setInterfaces(advised.getTargetSource().getInterfaces());
    enhancer.setCallback(new DynamicAdvisedInterceptor(advised));
    Object enhanced = enhancer.create();
    return enhanced;
  }

  private static class DynamicAdvisedInterceptor implements MethodInterceptor {

    private AdvisedSupport advised;

    private org.aopalliance.intercept.MethodInterceptor delegateMethodInterceptor;

    private DynamicAdvisedInterceptor(AdvisedSupport advised) {
      this.advised = advised;
      this.delegateMethodInterceptor = advised.getMethodInterceptor();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
      if (advised.getMethodMatcher() == null
          || advised.getMethodMatcher().matches(method, advised.getTargetSource().getTargetClass())) {
        return delegateMethodInterceptor.invoke(new CglibMethodInvocation(advised.getTargetSource().getTarget(), method, args, proxy));
      }
      return new CglibMethodInvocation(advised.getTargetSource().getTarget(), method, args, proxy).proceed();
    }
  }

  private static class CglibMethodInvocation extends ReflectiveMethodInvocation {

    private final MethodProxy methodProxy;

    public CglibMethodInvocation(Object target, Method method, Object[] args, MethodProxy methodProxy) {
      super(target, method, args);
      this.methodProxy = methodProxy;
    }

    @Override
    public Object proceed() throws Throwable {
      return this.methodProxy.invoke(this.target, this.arguments);
    }
  }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值