java - 如何使用 ExposeBeanNameAdvisors`

标签 java spring spring-aop

我需要找到我代理的 bean 的名称。这是一些背景:

我有以下 xml 配置,它使用 BeanNameAutoProxyCreator,根据名称代理不同的 Bean(使用 NameMatchMethodPointcutAdvisor):

<bean id="myAdvisor" class="some.package.MyAdvisor"/>
  <bean id="myProxy"
      class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"
      p:proxyTargetClass="true">
    <property name="beanNames">
        <list>
            <value>*someBean</value>
        </list>
    </property>
    <property name="interceptorNames">
        <list>
            <value>someInterceptor</value>
        </list>
    </property>
</bean>

<bean id="someInterceptor"
      class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
    <property name="mappedName" value="methodName"/>
    <property name="advice" ref="myAdvisor"/>
</bean>

这是我的顾问的实现。我希望能够在这个顾问中获得 bean 的名称。

public class MyAdvisor implements MethodInterceptor {
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
      // I want to be able to get the bean name of this method invocation here

      try {
          long startTime = System.nanoTime();
          log(startTime);

          return methodInvocation.proceed();
      }
      finally {
          long endTime = System.nanoTime();
          log(endTime);
      }
    }

}

我知道有一个 ExposeBeanNameAdvisors 类提供了一个我可以使用的方便的 getBeanName(MethodInitation mi) 方法。但是,我不明白“假设 ExposeBeanNameAdvisor 已包含在拦截器链中”是什么意思。 (来自 javadoc)你们能给我一个如何使用 ExposeBeanNameAdvisors 的示例吗?

谢谢!

最佳答案

ExposeBeanNameAdvisors 有两个静态方法createAdvisorWithoutIntroductioncreateAdvisorIntroducingNamedBean,它们返回一个Advisor对象,该对象应该添加到您的顾问堆栈中。

如果你看看其中之一的实现

private static class ExposeBeanNameInterceptor implements MethodInterceptor {

    private final String beanName;

    public ExposeBeanNameInterceptor(String beanName) {
        this.beanName = beanName;
    }

    public Object invoke(MethodInvocation mi) throws Throwable {
        if (!(mi instanceof ProxyMethodInvocation)) {
            throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
        }
        ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
        pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, this.beanName);
        return mi.proceed();
    }
}

您会注意到,bean 名称作为属性添加到 MethodInitation 中,该属性被强制转换为 ProxyMethodInitation。这需要位于自定义顾问之前的代理调用堆栈中,以便您可以使用 ExposeBeanNameAdvisors.getBeanName() 检索 Bean 名称,否则您会收到异常。

关于java - 如何使用 ExposeBeanNameAdvisors`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20614353/

相关文章:

java - 错误 : android. view.InflateException: Binary XML file line #8: Binary XML file line #8: Error inflating class fragment

java - Jersey 客户端和 CXF 混淆(多部分问题)

java - 在 Spring 中使用 Thymeleaf 代替 JSP 有什么优势?

java - 用于 OneToMany 的 Spring RowMapper?

java - Spring @Transaction 方法被同一个类内的方法调用,不起作用?

java - BeanNotOfRequiredTypeException 但实际上是 $Proxy 类型

java - 在二叉树中搜索字符串

java - Spring Autowiring 仅扫描测试文件

java - Spring Boot自定义分页参数

java - Spring @Around > 参数的行为