首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >春季-AOP加载时在第三方类上的编织

春季-AOP加载时在第三方类上的编织
EN

Stack Overflow用户
提问于 2014-09-17 15:34:39
回答 1查看 2K关注 0票数 1

我写了一个用junit测试的方面。这个方面在一个名为setQuery的第三方方法上有一个@Around建议。在编译时,它会抱怨:Can't find referenced pointcut setQuery

这是我的一面:

代码语言:javascript
运行
复制
@Component
@Aspect
public class ElasticsearchQuerySecurityAspect {
    @Around("org.elasticsearch.action.search.SearchRequestBuilder.setQuery() && args(queryBuilder)")
    public void addFilter(final ProceedingJoinPoint pjp, QueryBuilder queryBuilder) throws Throwable {
      Object[] args = pjp.getArgs();

      // Set the filter to use our plugin
      FilterBuilder securityFilter = FilterBuilders.scriptFilter("visibility-filter")
            .lang("native")
            .addParam("visibility-field", "visibility")
            .addParam("parameter", "default");

      // Re-create original query with the filter applied
      QueryBuilder newQuery = QueryBuilders.filteredQuery(queryBuilder,securityFilter);
      log.info("Adding filter to search request");
        // Tell the method to run with the modified parameter
        args[0] = newQuery;
        pjp.proceed(args);
    }
}

这是我的junit测试:

代码语言:javascript
运行
复制
@RunWith(SpringJUnit4ClassRunner.class)// NOTE #1
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
@EnableLoadTimeWeaving
@ComponentScan
public class ElasticsearchQuerySecurityTest {

  Client client = mock(Client.class);

  @Before
  public void setUp() throws Exception {
  }

  @Test
  public void test() {    
    SearchRequestBuilder s = new SearchRequestBuilder(client);
    QueryBuilder qb = QueryBuilders.queryString("name:foo");
        XContentBuilder builder;
    try {
      builder = XContentFactory.jsonBuilder();
      qb.toXContent(builder, null);
      assertEquals("{\"query_string\":{\"query\":\"name:foo\"}}",builder.string());

      // Call setQuery() which will invoke the security advice and add a filter to the query
      s.setQuery(qb);
      builder = XContentFactory.jsonBuilder().startObject();
      qb.toXContent(builder, null);
      builder.endObject();
      assertEquals("{\"query\": "+
        "{ \"filtered\": "+
        "{ \"query\": "+
        "{ \"query_string\": "+
        "{ \"name:foo\", } }, "+
        "\"filter\": "+
        "{ \"script\": "+
        "{ \"script\": \"visibility-filter\","+
        "\"lang\":\"native\", "+
        "\"params\": "+
        "{ \"visibility-field\":\"visibility\", "+
        "\"parameter\":\"default\" } } } } } }",
        builder.string());
    } catch (IOException e) {
      fail("We threw an I/O exception!");
    }   
  }
}

我在类路径上也有这个aop.xml:

代码语言:javascript
运行
复制
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>

    <weaver>
        <include within="org.elasticsearch.action.search.*"/>
    </weaver>

    <aspects>
        <aspect name="org.omaas.security.ElasticsearchQuerySecurityAspect"/>
    </aspects>

</aspectj>

我尝试了@Around("execution(public * set*())")的一个方面,发现它只建议当前包中的内容。我怎样才能把它应用到第三方包里的东西上?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-25 09:23:25

春天的AOP只能编织成春豆。由于第三方目标类不是Spring,因此无法对其应用方面。为此,您需要使用AspectJ,它功能更强大,不依赖基于动态代理的Spring的“AspectJ”实现。

对于AspectJ,您有两个选项:

  • 编译时编织(CTW):您可以将方面编译到第三方类中,并为您的依赖创建一个新的方面增强JAR。
  • 加载时编织(LTW):您可以在运行时将方面编织到第三方类中。在引导应用程序时,这需要几个CPU周期,但不必重新打包第三方JAR。

编辑:哦,顺便说一下,切入点语法是无效的。你不能写

代码语言:javascript
运行
复制
@Around("org.elasticsearch.action.search.SearchRequestBuilder.setQuery() && args(queryBuilder)")

相反,你更需要这样的东西

代码语言:javascript
运行
复制
@Around("execution(* org.elasticsearch.action.search.SearchRequestBuilder.setQuery(*)) && args(queryBuilder)")

一个方法名称是不够的,您必须告诉AOP框架您想要捕获它的execution() (在AspectJ中,cou也可以通过call()捕获其所有调用者)。其次,您将不会通过指定没有任何参数的方法签名setQuery()来捕获具有一个setQuery()参数的方法,因此,我建议您使用setQuery(*),或者,如果您想更精确地使用setQuery(org.elasticsearch.index.query.QueryBuilder)。您还需要一个返回类型和/或修饰符,比如方法名前面的public,或者像*这样的joker。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25894767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档