切入点以匹配对除 frm jdk 之外的任何方法的调用
Pointcut to match call to any method except those frm jdk
我希望我的切入点标记对除 java sdk
中的方法之外的任何方法的调用
Pointcut trace(): call(* *(..)) && !within(methodprofilt) && !call(* java*(..)
这行不通
我正在寻找的切入点是
call(java..*..*(..))
我认为这不是那么容易,如果你查看 JDK,你会发现除了 java..*
之外还有很多包名称。查看我的示例代码,它使用来自其他包的 JDK classes(还有更多,这只是一个小展示),一些用于正常访问,另一些用于限制访问:
帮手class:
package de.scrum_master.app;
public class Foo {
public static void doSomething() {
System.out.println("Doing something");
}
}
驱动申请:
package de.scrum_master.app;
import javax.swing.event.EventListenerList;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.Oid;
import org.omg.CORBA.IntHolder;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.xml.sax.InputSource;
// Internal Sun/Oracle-specific JDK classes,
// not recommended for JDK- and version-agnostic use
import sun.util.calendar.CalendarUtils;
import com.sun.beans.finder.BeanInfoFinder;
public class Application {
public static void main(String[] args)
throws GSSException, ClassNotFoundException, InstantiationException,
IllegalAccessException, ClassCastException
{
sayHelloTo("world");
Foo.doSomething();
new Oid("1.2.840.113554.1.2.2").getDER();
System.out.println("Process ID (PID) = " + getPID());
new IntHolder(11)._type();
DOMImplementationRegistry.newInstance().getDOMImplementation("XML 3.0");
new InputSource().setEncoding("UTF-8");
new EventListenerList().getListenerCount();
// Internal Sun/Oracle-specific JDK classes,
// not recommended for JDK- and version-agnostic use
new BeanInfoFinder().getPackages();
new CalendarUtils().isGregorianLeapYear(2015);
}
public static void sayHelloTo(String visitor) {
System.out.println("Hello " + visitor);
}
public static long getPID() {
String processName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
return Long.parseLong(processName.split("@")[0]);
}
}
改进的拦截器方面:
package de.scrum_master.aspect;
public aspect NonJDKInterceptor {
pointcut allCalls() : call(* *(..));
pointcut jdkCalls() :
call(* java..*(..)) || call(* javax..*(..)) ||
call(* org.ietf..*(..)) || call(* org.omg..*(..)) ||
call(* org.w3c..*(..)) || call(* org.xml..*(..)) ||
call(* sun..*(..)) || call(* com.sun..*(..));
before() : allCalls() && !jdkCalls() && !within(NonJDKInterceptor) {
System.out.println(thisJoinPoint);
}
}
控制台输出:
call(void de.scrum_master.app.Application.sayHelloTo(String))
Hello world
call(void de.scrum_master.app.Foo.doSomething())
Doing something
call(long de.scrum_master.app.Application.getPID())
Process ID (PID) = 13948
您的简单切入点会错过大部分 JDK 调用。只有这个切入点
pointcut jdkCalls() : call(* java..*(..));
输出如下所示:
call(void de.scrum_master.app.Application.sayHelloTo(String))
Hello world
call(void de.scrum_master.app.Foo.doSomething())
Doing something
call(byte[] org.ietf.jgss.Oid.getDER())
call(long de.scrum_master.app.Application.getPID())
Process ID (PID) = 13748
call(TypeCode org.omg.CORBA.IntHolder._type())
call(DOMImplementationRegistry org.w3c.dom.bootstrap.DOMImplementationRegistry.newInstance())
call(DOMImplementation org.w3c.dom.bootstrap.DOMImplementationRegistry.getDOMImplementation(String))
call(void org.xml.sax.InputSource.setEncoding(String))
call(int javax.swing.event.EventListenerList.getListenerCount())
call(String[] com.sun.beans.finder.BeanInfoFinder.getPackages())
call(boolean sun.util.calendar.CalendarUtils.isGregorianLeapYear(int))
更新: 我忘了提到使用 execution()
切入点而不是 call()
的替代方法,因为它们
- 效率更高,因为它们在执行方法的地方创建字节码,而不是在调用它的一百个地方,
- 默认情况下只会编入您自己的代码,即无论如何您都不会编入JDK二进制文件,因此默认情况下会忽略JDK方法执行。简化方面变为:
package de.scrum_master.aspect;
public aspect NonJDKInterceptor {
before() : execution(* *(..)) {
System.out.println(thisJoinPoint);
}
}
日志输出与第一个类似,但现在它还列出了main(..)
方法的执行:
execution(void de.scrum_master.app.Application.main(String[]))
execution(void de.scrum_master.app.Application.sayHelloTo(String))
Hello world
execution(void de.scrum_master.app.Foo.doSomething())
Doing something
execution(long de.scrum_master.app.Application.getPID())
Process ID (PID) = 13916
我认为这是您想要的简单高效的解决方案。可能会回答 call()
切入点正是您所要求的。
我希望我的切入点标记对除 java sdk
中的方法之外的任何方法的调用Pointcut trace(): call(* *(..)) && !within(methodprofilt) && !call(* java*(..)
这行不通
我正在寻找的切入点是
call(java..*..*(..))
我认为这不是那么容易,如果你查看 JDK,你会发现除了 java..*
之外还有很多包名称。查看我的示例代码,它使用来自其他包的 JDK classes(还有更多,这只是一个小展示),一些用于正常访问,另一些用于限制访问:
帮手class:
package de.scrum_master.app;
public class Foo {
public static void doSomething() {
System.out.println("Doing something");
}
}
驱动申请:
package de.scrum_master.app;
import javax.swing.event.EventListenerList;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.Oid;
import org.omg.CORBA.IntHolder;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.xml.sax.InputSource;
// Internal Sun/Oracle-specific JDK classes,
// not recommended for JDK- and version-agnostic use
import sun.util.calendar.CalendarUtils;
import com.sun.beans.finder.BeanInfoFinder;
public class Application {
public static void main(String[] args)
throws GSSException, ClassNotFoundException, InstantiationException,
IllegalAccessException, ClassCastException
{
sayHelloTo("world");
Foo.doSomething();
new Oid("1.2.840.113554.1.2.2").getDER();
System.out.println("Process ID (PID) = " + getPID());
new IntHolder(11)._type();
DOMImplementationRegistry.newInstance().getDOMImplementation("XML 3.0");
new InputSource().setEncoding("UTF-8");
new EventListenerList().getListenerCount();
// Internal Sun/Oracle-specific JDK classes,
// not recommended for JDK- and version-agnostic use
new BeanInfoFinder().getPackages();
new CalendarUtils().isGregorianLeapYear(2015);
}
public static void sayHelloTo(String visitor) {
System.out.println("Hello " + visitor);
}
public static long getPID() {
String processName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
return Long.parseLong(processName.split("@")[0]);
}
}
改进的拦截器方面:
package de.scrum_master.aspect;
public aspect NonJDKInterceptor {
pointcut allCalls() : call(* *(..));
pointcut jdkCalls() :
call(* java..*(..)) || call(* javax..*(..)) ||
call(* org.ietf..*(..)) || call(* org.omg..*(..)) ||
call(* org.w3c..*(..)) || call(* org.xml..*(..)) ||
call(* sun..*(..)) || call(* com.sun..*(..));
before() : allCalls() && !jdkCalls() && !within(NonJDKInterceptor) {
System.out.println(thisJoinPoint);
}
}
控制台输出:
call(void de.scrum_master.app.Application.sayHelloTo(String))
Hello world
call(void de.scrum_master.app.Foo.doSomething())
Doing something
call(long de.scrum_master.app.Application.getPID())
Process ID (PID) = 13948
您的简单切入点会错过大部分 JDK 调用。只有这个切入点
pointcut jdkCalls() : call(* java..*(..));
输出如下所示:
call(void de.scrum_master.app.Application.sayHelloTo(String))
Hello world
call(void de.scrum_master.app.Foo.doSomething())
Doing something
call(byte[] org.ietf.jgss.Oid.getDER())
call(long de.scrum_master.app.Application.getPID())
Process ID (PID) = 13748
call(TypeCode org.omg.CORBA.IntHolder._type())
call(DOMImplementationRegistry org.w3c.dom.bootstrap.DOMImplementationRegistry.newInstance())
call(DOMImplementation org.w3c.dom.bootstrap.DOMImplementationRegistry.getDOMImplementation(String))
call(void org.xml.sax.InputSource.setEncoding(String))
call(int javax.swing.event.EventListenerList.getListenerCount())
call(String[] com.sun.beans.finder.BeanInfoFinder.getPackages())
call(boolean sun.util.calendar.CalendarUtils.isGregorianLeapYear(int))
更新: 我忘了提到使用 execution()
切入点而不是 call()
的替代方法,因为它们
- 效率更高,因为它们在执行方法的地方创建字节码,而不是在调用它的一百个地方,
- 默认情况下只会编入您自己的代码,即无论如何您都不会编入JDK二进制文件,因此默认情况下会忽略JDK方法执行。简化方面变为:
package de.scrum_master.aspect;
public aspect NonJDKInterceptor {
before() : execution(* *(..)) {
System.out.println(thisJoinPoint);
}
}
日志输出与第一个类似,但现在它还列出了main(..)
方法的执行:
execution(void de.scrum_master.app.Application.main(String[]))
execution(void de.scrum_master.app.Application.sayHelloTo(String))
Hello world
execution(void de.scrum_master.app.Foo.doSomething())
Doing something
execution(long de.scrum_master.app.Application.getPID())
Process ID (PID) = 13916
我认为这是您想要的简单高效的解决方案。可能会回答 call()
切入点正是您所要求的。