从外部库动态加载Java函数

时间:2014-12-11 08:54:01

标签: java

我正在开发一个不太精心设计的大型Java项目,我们实际上有两个主要的开发分支。 一个分支A是第二个分支B的子集,具有后者的所有功能,但没有在用户操作上集成安全检查(它们只是标记哪个用户做了什么的文件的哈希)。

由于开发是在A分支上完成的,每当修复错误时,我必须手动合并分支B上的所有工作。

代码库是巨大的,并且它具有相互依赖性,但重写它是没有讨论的(像往常一样创建问题)。此外,整个架构非常复杂,任何结构变化都可能产生奇怪的副作用。 (我意识到这是程序员的噩梦!)。

现在,我作为Java初学者的问题如下:是否有可能"外化"一些类的一些函数 - 即实现安全检查的所有函数 - 在外部库中,以便代码在jar文件中存在库时执行这些函数,并执行plain" no -security"其他功能呢?

为了清楚起见,这里有一个我想做的小示意图:

--- branch A ---
+ class ONE
  f1()
  f2()
+ class TWO
  g1()
  g2()

--- branch B ---
+ class ONE
  f1*()
  f2()
+ class TWO
  g1*()
  g2()

每当库不存在时,代码必须执行f1()和g1(),但如果库在那里则执行加星号版本。

理想情况下,考虑到上述问题,我想简单地剪切和粘贴与安全相关的"函数在一组java文件中,并将它们编译为库,我会在需要时手动执行这些函数的更改 - 它们通常不会被修改。

是否有其他方法可以解决这种情况,以防止出现这些问题?

提前多多感谢!

3 个答案:

答案 0 :(得分:0)

@ RH6,你问的肯定是可能的,但在你上面描述的情况下可能不是很容易。然而,如上所述,基本思想是寻找所讨论的库的存在/不存在并相应地表现。这更像是一个设计问题,并且有多种方法,所以从一开始,您应该准备修改您的设计以包含此行为。

您可以探索的一个途径是使用AspectJ和编织建议(围绕建议)。在这个建议体中,您可以检查是否存在所需的JAR,如果它存在,您可以使用自定义类加载器(尽管如果JAR在类路径上则没有必要)加载/创建所需类的对象和执行f1 *()/ g1 *()方法。如果JAR不存在,继续执行f1()/ g1()方法。

正如您所观察到的,上述方法稍微不那么具有干扰性(需要对现有代码库进行构建级别的入侵),但它需要您修改构建过程以及开发和编译。保持建议。

答案 1 :(得分:0)

我认为您不需要动态加载函数。例如,您可以:

  • 使B扩展A(并将其命名为SecuredA)并覆盖f1()和g1()以添加所需的安全检查。

  • 创建一个在f1()和g1()内部调用的SecurityManager接口。然后,您必须创建2个实现:一个不执行任何操作(= A),另一个执行与安全相关的功能(= B)。然后,您只需根据当前情况注入/使用正确的SecurityManager。

答案 2 :(得分:0)

有各种设计原则可以解决这个问题。

例如:IoC(控制反转)。

  

在软件工程中,控制反转(IoC)描述了一种设计,其中计算机程序的自定义编写部分从通用的可重用库中接收控制流。与传统的过程编程相比,具有此设计的软件体系结构颠倒了控制:在传统编程中,表达程序目的的自定义代码调用可重用库来处理通用任务,但是通过控制反转,它是可重用的调用自定义或特定于任务的代码的代码。

最流行的框架(据我所知)是 Spring 。在对象实例化期间,您将开始使用工厂方法。此工厂方法将检查XML文件是否可能进行覆盖。 这是一个例子:

<?xml version="1.0" encoding="UTF-8"?>
 <beans ...>
   <bean id="myClass" class="package.my.MyClass" />
 </beans>

或者如果您不喜欢Spring依赖项。您可以使用一些反射来创建自己的东西:

Class defaultClass = package.my.MyClass.class;
String overruledClassName = System.getProperty(defaultClassName.getName + ".clazz");
Class clazz = (overruledClassName == null) ? defaultClass : Class.forName(overruledClassName);
Object createdObject = clazz.newInstance();

与包含以下属性的属性文件结合使用:

package.my.MyClass.clazz = package.my.MyClassVersion2