首页
登录 | 注册

AOP之proceedingjoinpoint和joinpoint区别(获取各对象备忘)、动态代理机制及获取原理代理对象、获取Mybatis Mapper接口原始对象

现在AOP的场景越来越多,所以我们有必要理解下和AOP相关的一些概念和机制。
import org.aspectj.lang.reflect.SourceLocation;  
public interface JoinPoint {  
   String toString();         //连接点所在位置的相关信息  
   String toShortString();     //连接点所在位置的简短相关信息  
   String toLongString();     //连接点所在位置的全部相关信息  
   Object getThis();         //返回AOP代理对象,也就是com.sun.proxy.$Proxy18
   Object getTarget();       //返回目标对象,一般我们都需要它或者(也就是定义方法的接口或类,为什么会是接口呢?这主要是在目标对象本身是动态代理的情况下,例如Mapper。所以返回的是定义方法的对象如aoptest.daoimpl.GoodDaoImpl或com.b.base.BaseMapper<T, E, PK>)
   Object[] getArgs();       //返回被通知方法参数列表  
   Signature getSignature();  //返回当前连接点签名  其getName()方法返回方法的FQN,如void aoptest.dao.GoodDao.delete()或com.b.base.BaseMapper.insert(T)(需要注意的是,很多时候我们定义了子类继承父类的时候,我们希望拿到基于子类的FQN,这直接可拿不到,要依赖于AopUtils.getTargetClass(point.getTarget())获取原始代理对象,下面会详细讲解)
   SourceLocation getSourceLocation();//返回连接点方法所在类文件中的位置  
   String getKind();        //连接点类型  
   StaticPart getStaticPart(); //返回连接点静态部分  
  }  
 
 public interface ProceedingJoinPoint extends JoinPoint {  
       public Object proceed() throws Throwable;  
       public Object proceed(Object[] args) throws Throwable;  
 } 
JoinPoint.StaticPart:提供访问连接点的静态部分,如被通知方法签名、连接点类型等:
public interface StaticPart {  
   Signature getSignature();    //返回当前连接点签名  
   String getKind();          //连接点类型  
   int getId();               //唯一标识  
   String toString();         //连接点所在位置的相关信息  
   String toShortString();     //连接点所在位置的简短相关信息  
   String toLongString();     //连接点所在位置的全部相关信息  
}

环绕通知 ProceedingJoinPoint 执行proceed方法的作用是让目标方法执行,这也是环绕通知和前置、后置通知方法的一个最大区别。

 Proceedingjoinpoint 继承了 JoinPoint 。是在JoinPoint的基础上暴露出 proceed 这个方法。proceed很重要,这个是aop代理链执行的方法。

AOP之proceedingjoinpoint和joinpoint区别(获取各对象备忘)、动态代理机制及获取原理代理对象、获取Mybatis Mapper接口原始对象

 

暴露出这个方法,就能支持 aop:around 这种切面(而其他的几种切面只需要用到JoinPoint,这跟切面类型有关), 能决定是否走代理链还是走自己拦截的其他逻辑。建议看一下 JdkDynamicAopProxy的invoke方法,了解一下代理链的执行原理。
典型的用法如下:
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Signature signature = point.getSignature();
// AopUtils.getTargetClass(point.getTarget())获取原始对象,例如对于Mapper而言,它获取的是具体代理的Mapper如com.b.mapper.DefaultDsMapper(如果前者继承了后者的话)而不是定义该方法的Mapper如com.b.base.BaseMapper<Info, InfoExample, InfoKey>,如下图 Type[] types
= AopUtils.getTargetClass(point.getTarget()).getGenericInterfaces(); // getGenericInterfaces方法能够获取类/接口实现的所有接口 Annotation nologgingAnno = ((Class)types[0]).getAnnotation(Nologging.class); // type是所有类型的父接口 MethodSignature methodSignature = (MethodSignature)signature; Method targetMethod = methodSignature.getMethod();

 

AOP之proceedingjoinpoint和joinpoint区别(获取各对象备忘)、动态代理机制及获取原理代理对象、获取Mybatis Mapper接口原始对象

 

现在来补充下Java中Type接口与Class类的区别联系。

package java.lang.reflect;

/**
 * Type is the common superinterface for all types in the Java
 * programming language. These include raw types, parameterized types,
 * array types, type variables and primitive types.
 *
 * @since 1.5
 */
public interface Type {
    /**
     * Returns a string describing this type, including information
     * about any type parameters.
     *
     * @implSpec The default implementation calls {@code toString}.
     *
     * @return a string describing this type
     * @since 1.8
     */
    default String getTypeName() {
        return toString();
    }
}

其主要的子类包括:

AOP之proceedingjoinpoint和joinpoint区别(获取各对象备忘)、动态代理机制及获取原理代理对象、获取Mybatis Mapper接口原始对象

 

总结来说:

  • Type是一个接口。
  • Type是Java中所有类型的父接口,有一些子类,如上所示。
  • Type包括:raw type(原始类型,对应Class),parameterized types(参数化类型), array types(数组类型), type variables(类型变量) and primitive types(基本类型,对应Class).
  • Type是JDK1.5引入的,主要是为了泛型。

Type接口与Class类的区别联系

  • Type是Class的父接口。
  • Class是Type的子类。

相关文章

  • 目录 引入 简单工厂 抽象工厂 Spring的bean工厂 模拟Spring工厂实现 模拟IOC 引入 假设有一个司机, 需要到某个城市, 于是我们给他一辆汽车 public class Demo { public static void ...
  • More Effective C++
    More Effective C++ 35个改善编程与设计的有效方法 只有深入了解C++编译器如何解释代码, 才有可能用C++语言写出健壮的软件. C++的难学, 不仅在其广博的语法, 语法背后的语义, 语义背后的深层思维, 深层思维背后的 ...
  • ASP.NET Core - 依赖注入
    考虑到主题问题,在这里不打算详细讲解依赖注入的概念,需要了解依赖注入的可以关注我的DI&IoC分类讲解,这里我们专注于ASP.NET Core 体系中系统自带的原生IoC容器是如何让我们实现注入和解析的. 服务的生命周期 在开始之前 ...
  • ASP.NET Core - 从Program和Startup开始
    Program 我们先看一下1.x和2.x的程序入口项的一个差异 1.x public class Program { public static void Main(string[] args) { var host = new WebH ...
  • 转载请标明出处:http://www.cnblogs.com/zblade/ 一.概述 整理遇到的一些较难处理的bug,总结相关经验 二.主要问题 2.1 material类型的依赖修改 对于material类型的asset,如果修改了其s ...
  • 当我们无法获取ip地址时可以使用dhcp来动态获取ip地址,安装dhcpcd5和dhcpcd-gtk sudo apt-get install dhcpcd5 sudo apt-get install dhcpcd-gtk 使用ifconf ...

2019 cecdns.com webmaster#cecdns.com
12 q. 0.081 s.
京ICP备10005923号