当前位置: 首页 > 知识库问答 >
问题:

处理AOP反射代理:“对象不是声明类的实例”

齐献
2023-03-14

我的应用程序需要对Spring bean执行动态调用。我扫描Spring bean以查找带有自定义注释的方法,并存储对method对象的引用,以备将来调用。

public Method getMethod(Class<?> clazz, final String name) throws ReflectiveOperationException, NoSuchMethodException
{
    Method meth = null;

    for (Method m : clazz.getMethods())
    {
        String alias;
        WorkflowMethod annotation = m.getAnnotation(WorkflowMethod.class);
        if (annotation == null)
        {
            log.warn(...);
            continue;
        }

        alias = annotation.alias();
        if (StringUtils.isEmpty(alias))
            alias = m.getName();
        if (!name.equals(alias))
            continue;

        if (meth != null)
            throw new Exception(...);

        meth = m;
    }


    if (meth == null)
        throw new NoSuchMethodException(...);
    return meth;
}

上面的代码将根据一个方法没有重载(按需求)的事实,按名称提取它。

但是,当我在后面的代码中尝试调用meth.invoke(springBean,params)时,我得到了标题中描述的InvocationTargetException

我所有的bean都是AOP代理,因为我使用Spring事务。

我使用以下代码获得clazz变量,因为AOP代理不显示源类中注释

    Class<?> managerClass;
    if (workflowManager instanceof TargetClassAware)
        managerClass = ((TargetClassAware) workflowManager).getTargetClass();
    else
        managerClass = workflowManager.getClass();

总而言之,我需要使用targetClassAware,因为否则我将无法扫描注释,但是如果我从原始类获得一个方法,它将与代理类不兼容。

共有1个答案

周浩博
2023-03-14

当我写问题的时候,我自己找到了答案。

我的想法是对的:我不能扫描AOP代理,否则我就无法获得注释,但是我必须从代理本身而不是从原始类中选择方法。

方法如下:扫描目标类以查找带注释的方法,但然后从代理类中选择相同的方法(相同的名称和参数)。代码可以通过两种方式修改,这里是一种:

public Method getMethod(Class<?> targetClass, Class<?> proxyClass, final String name) throws ReflectiveOperationException, NoSuchMethodException
{
    Method meth = null;

    for (Method m : targetClass.getMethods())
    {
        String alias;
        WorkflowMethod annotation = m.getAnnotation(WorkflowMethod.class);
        if (annotation == null)
        {
            log.warn("...);
            continue;
        }

        alias = annotation.alias();
        if (StringUtils.isEmpty(alias))
            alias = m.getName();
        if (!name.equals(alias))
            continue;

        if (meth != null)
            throw new Exception(...);
        if (proxyClass == null)
            meth = m;
        else
            meth = proxyClass.getMethod(m.getName(), m.getParameterTypes());
    }

    if (meth == null)
        throw new NoSuchMethodException(...);
    return meth;
}
 类似资料:
  • 用户类 我把这个复制方法叫做 并在执行writeMethod.invoke(dest,val)时获得以下异常。有人能帮忙吗? 对象不是在java.base/jdk.internal.reflect.nativeMethodAccessorImpl.Invoke0(原生方法)在java.base/jdk.internal.reflect.nativeMethodAccessorImpl.Invoke

  • 问题内容: 我已经有一段时间没有接触过Mockito了,我也从未广泛使用它。但是今天,在一些新代码中,我想使用最佳实践,因此我使用以下Java版本退出了模仿内核2.0.54-beta: 我需要此接口的实例进行测试: https://bitbucket.org/globalmentor/rincl/src/bf0e8875a1bae16247dd904e0b8bc067c9f8abc9/src/ma

  • 我有一段时间没有接触过Mockito,也从来没有大量使用过它。但是今天在一些新代码中,我希望使用最佳实践,所以我使用以下Java版本推出了mockito-core 2.0.54-beta: 要重现此问题,请克隆https://bitbucket.org/globalmentor/rincl.git并签出commit2f88d7c5e5ac17b6d316ed54c12cb7b447b7d6ac。然

  • 本文向大家介绍详解Java反射实现Aop代理,包括了详解Java反射实现Aop代理的使用技巧和注意事项,需要的朋友参考一下 利用反射生成JDK的动态代理,也就是AOP中的AOP代理,代替目标对象,从而在代码中织入增强。 定义代理接口 由于JDKf动态代理只能为接口创建动态代理,故先定义接口,假定我们需要对数据的Save方法添加事务处理,我们有一个UserDao接口,里面有一个Save方法,代码如下

  • 问题内容: 这个问题在Google上到处都有,但我仍然遇到问题。这就是我想要做的。因此,就像标题状态一样,我遇到了“对象不是声明类的实例”错误。有任何想法吗?谢谢! Main.java TestFunction.java 问题答案: 您正在使用该类调用该方法,但需要一个实例。试试这个:

  • 我已经设置了一个Spring Boot项目,并使用castor xml依赖关系将POJO转换为xml。 在为POJO调用封送处理方法时遇到问题。我查阅了stackoverflow的其他相关问题,但没有一个能解决我的场景。 有一个toString方法,它位于Spring组件中。 以下是片段: 这是客户端内部的封送方法(castor之前自动生成的类): 以下是相同的堆栈跟踪: 这里需要注意的是,当我执