枚举加载时编织方面?

时间:2011-12-21 11:28:53

标签: java aspectj

使用AspectJ,我可以使用aspectOf()方法获取方面的单例实例:

MyAspect aspect = Aspects.aspectOf(MyAspect.class);

// now perform post-application startup initialisation, eg:
aspect.setLogService(logging); 

有没有办法在我正在运行的Java应用程序中获取所有方面的列表?我正在使用带有加载时编织的AspectJ 1.6.7,但如果需要可以升级版本。

我的应用程序中所有方面的列表将允许我在启动时将依赖项注入其中。

2 个答案:

答案 0 :(得分:1)

一个相当hackish的解决方案,但仍然是一个解决方案:从类路径手动加载aop.xml文件并解析它以获取方面类名称:

final Enumeration<URL> urls =
  getClass().getClassLoader().getResources("META-INF/aop.xml");

final Collection<String> aspectNames = new ArrayList<String>();

for (final URL url : urls) 
{
    final Stream xml = url.openStream();

    final DocumentBuilderFactory docBuilderFactory = 
      DocumentBuilderFactory.newInstance();
    docBuilderFactory.setValidating(false);
    docBuilderFactory.setNamespaceAware(false);

    final XPath xpath = XPathFactory.newInstance().newXPath();
    final Document aspectXml = docBuilderFactory.newDocumentBuilder().parse(xml);
    final XPathExpression selector = xpath.compile("//aspect/@name");

    final NodeList matches = 
      (NodeList) selector.evaluate(aspectXml, XPathConstants.NODESET);

    for (int i = 0; i < matches.getLength(); i++) 
    {
        aspectNames.add(matches.item(i).getNodeValue());
    }    
}

然后可以像这样获取方面实例:

for (final String className : aspectNames) 
{
    final Class<?> aspectClass = Class.forName(className);
    final Object aspect = Aspects.aspectOf(aspectClass);

    // finally (!) do the initialisation on the aspect itself:
    aspect.setLogService(logging);
}

答案 1 :(得分:0)

如果您不想列出您的每个方面,那么您是否应该考虑使用另一个方面来注入您的依赖项?

如果没有,您的DI框架可能会提供一些有用的机制。