海兴县网站建设公司,软件工程大学排名,设计logo网站免费奇米,巩义做网站的对于那些使用第三方工具来尝试扩展它们而又不完全了解它们的人来说#xff0c;这是一个小技巧。 假定以下情况#xff1a; 您想扩展一个公开分层数据模型的库#xff08;假设您要扩展Apache Jackrabbit #xff09; 该库在访问内容存储库的任何节点之前会内部检查访问权限… 对于那些使用第三方工具来尝试扩展它们而又不完全了解它们的人来说这是一个小技巧。 假定以下情况 您想扩展一个公开分层数据模型的库假设您要扩展Apache Jackrabbit 该库在访问内容存储库的任何节点之前会内部检查访问权限 您想实现自己的访问控制算法 您的访问控制算法将访问内容存储库的其他节点 …反过来又会触发访问控制 …进而将再次访问内容存储库的其他节点 …无限递归如果不递归广度优先则可能会导致StackOverflowError 。 现在您有两个选择 花时间坐下来了解内部原理并正确地做。 到达自己的扩展名后您可能不应该递归到访问控制中。 在扩展Jackrabbit的情况下这可以通过使用系统会话来进一步访问访问控制算法中的节点来完成。 系统会话通常绕过访问控制。 急躁想快速获得结果并通过技巧来防止递归 当然您确实应该选择选项1。但是谁有时间了解所有内容 这是实现该技巧的方法。 /*** This thread local indicates whether youve* already started recursing with level 1*/
static final ThreadLocalBoolean RECURSION_CONTROL new ThreadLocalBoolean();/*** This method executes a delegate in a protected* mode, preventing recursion. If a inadvertent* recursion occurred, return a default instead*/
public static T T protect(T resultOnRecursion,ProtectableT delegate)
throws Exception {// Not recursing yet, allow a single level of// recursion and execute the delegate onceif (RECURSION_CONTROL.get() null) {try {RECURSION_CONTROL.set(true);return delegate.call();}finally {RECURSION_CONTROL.remove();}}// Abort recursion and return earlyelse {return resultOnRecursion;}
}/*** An API to wrap your code with*/
public interface ProtectableT {T call() throws Exception;
} 在此用法示例中可以很容易地看出这一点 public static void main(String[] args)
throws Exception {protect(null, new ProtectableVoid() {Overridepublic Void call() throws Exception {// Recurse infinitelySystem.out.println(Recursing?);main(null);System.out.println(No!);return null;}});
} 对main()方法的递归调用将被保护方法终止并提早返回而不是执行call() 。 也可以通过使用ThreadLocals Map进一步详细说明此思想从而允许指定各种键或上下文以防止递归。 然后您还可以将Integer放入ThreadLocal 在递归时将其递增最多允许N个递归级别。 static final ThreadLocalInteger RECURSION_CONTROL new ThreadLocalInteger();public static T T protect(T resultOnRecursion,ProtectableT delegate)
throws Exception {Integer level RECURSION_CONTROL.get();level (level null) ? 0 : level;if (level 5) {try {RECURSION_CONTROL.set(level 1);return delegate.call();}finally {if (level 0)RECURSION_CONTROL.set(level - 1);elseRECURSION_CONTROL.remove();}}else {return resultOnRecursion;}
} 但是再说一次。 也许您应该再花几分钟时间了解主机库的内部机制是如何工作的并从一开始就将事情做好……与往常一样在使用技巧和黑客手段时 参考在JavaSQL和JOOQ博客上我们的JCG合作伙伴 Lukas Eder 提供了Java ThreadLocals的意外递归保护 。 翻译自: https://www.javacodegeeks.com/2013/04/inadvertent-recursion-protection-with-java-threadlocals.html