如何在方面内使用ajc构建参数?

我需要在方面内知道我的.jar的名称,这样我就可以通过@DeclareParents创建一个字符串字段。

我知道我可以将内容传递给ajc编译器,但实际上是否可以使用方面传递的参数? 最终结果应该是带有附加字段的类,其中包含我的.jar名称作为值。

更新:建议测试。 Gson.jar是类路径上的.jar

InputStream r = Gson.class.getClassLoader().getResourceAsStream("META-INF/MANIFEST.MF"); String x = getString(r); System.out.println(x); 

输出:

 Manifest-Version: 1.0 Name: org/aspectj/lang/ Specification-Title: AspectJ Runtime Classes Specification-Version: 1.7 Specification-Vendor: aspectj.org Implementation-Title: org.aspectj.tools Implementation-Version: 1.7.3 Implementation-Vendor: aspectj.org Bundle-Name: AspectJ Runtime Bundle-Version: 1.7.3 Bundle-Copyright: (C) Copyright 1999-2001 Xerox Corporation, 2002 Palo Alto Research Center, Incorporated (PARC), 2003-2009 Contributors. All Rights Reserved. 

似乎同时只能有一个MANIFEST.MF资源,而AspectJ.jar恰好是类路径上的第一个。

我不知道怎么做你想要的。 即使可能,如果解压缩JAR并从文件系统加载修改后的类或重新打包/重命名JAR,字符串值仍将是相同的。 解决方案是静态的,而不是动态的。

无论如何,如何将这样的信息放入打包到JAR中的配置文件中,甚至可能直接放入清单文件中? Maven具有向清单添加信息的function,Java可以在运行时读取它们。 我没有想过,更不用说尝试实现类似的东西,但也许这是你可以去的方式。

随意提出后续问题。


更新:您可以避免清单方法并尝试直接确定每个已加载类的JAR文件,另请参阅此答案 。

实用类:

 package de.scrum_master.util; import java.net.URL; public class ClassFileHelper { public static URL getClassURL(Class clazz) { return clazz.getResource('/' + clazz.getName().replace('.', '/') + ".class"); } public static String getJARFromURL(URL url) { if (!url.getProtocol().equals("jar")) return null; String fileName = url.getFile(); fileName = fileName.substring(0, fileName.lastIndexOf('!')); fileName = fileName.substring(fileName.lastIndexOf('/') + 1); return fileName; } } 

用法:

我在Java + AspectJ项目中尝试过这种方法,其中方面包装在JAR文件中,Java文件存储在文件系统目录中。 我刚刚在JAR中的一个方面添加了以下建议:

 before() : execution(public static void main(..)) { try { Class[] classes = { String.class, this.getClass(), Class.forName("com.BadReader") }; for (Class clazz : classes) { System.out.println(clazz); URL classURL = ClassFileHelper.getClassURL(clazz); System.out.println(classURL); System.out.println(ClassFileHelper.getJARFromURL(classURL)); System.out.println(); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } 

如您所见,数组包含

  • 一个JRE引导类( String ),
  • 方面类本身( this.getClass() ),
  • 来自JAR之外的Java项目的类( Class.forName("com.BadReader") )。

控制台输出:

 class java.lang.String jar:file:/C:/Programme/Java/jre7/lib/rt.jar!/java/lang/String.class rt.jar class com.SafeReaderAspect jar:file:/C:/Users/Alexander/Documents/java-src/SO_AJ_ITD2StepCompilation_AspectJ/aspectLib.jar!/com/SafeReaderAspect.class aspectLib.jar class com.BadReader file:/C:/Users/Alexander/Documents/java-src/SO_AJ_ITD2StepCompilation_Java/bin/com/BadReader.class null 

这是你想要的吗?