Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java类中创建只能从一个其他类访问的方法_Java_Spring - Fatal编程技术网

如何在Java类中创建只能从一个其他类访问的方法

如何在Java类中创建只能从一个其他类访问的方法,java,spring,Java,Spring,我想知道是否有人有一个模式可以帮助我实现以下目标: 我们有一个名为Employee的JPA实体,上面有一个setLineManager方法。我们还有一个单独的updateLineStructureService,它是一个Spring管理的服务bean。我们希望尝试并确保此setLineManager方法只能从updateLineStructureService调用,而不能直接从任何其他类调用 是否有一种方法允许服务访问此方法而不将其公开给任何其他类?我知道我可以授予方法包级别的访问权,并将服务与

我想知道是否有人有一个模式可以帮助我实现以下目标:

我们有一个名为Employee的JPA实体,上面有一个setLineManager方法。我们还有一个单独的updateLineStructureService,它是一个Spring管理的服务bean。我们希望尝试并确保此setLineManager方法只能从updateLineStructureService调用,而不能直接从任何其他类调用

是否有一种方法允许服务访问此方法而不将其公开给任何其他类?我知道我可以授予方法包级别的访问权,并将服务与员工放在同一个包中,但这不适合我们的包结构,因此我不希望这样做。我也知道,我可以将该方法设置为私有,并在这个地方通过反射来访问它,但我一点也不喜欢这种解决方案


有什么想法吗?

您可以检查stacktrace(使用)并查看它是否在指定位置包含允许的方法。

类访问其他类的私有方法的唯一方法是使用内部类。如果这不是一个选项,那么就不能这样做。

一种方法是制作两种形式的员工

“BasicEmployee”具有除setLineManager()之外的所有方法。“ExtendedEmployee”扩展了基本员工并添加了一个
公共void setLineManager()
。(我假设这些是类,但也可以是接口)在幕后,一切都是一个完整的员工(为了清楚起见,你可以将BasicEmployee抽象化)。但是,在代码中,在除UpdateLineStructureService之外的所有类中,都将其声明为BasicEmployee。仅在UpdateLineStructureService中声明为FullEmployee。因此,只有UpdateLineStructureService可以轻松访问setLineManager()


现在,流氓程序员总是可以将他们的基本员工强制转换为ExtendedEmployee来访问setLineManager(),所以这不是完全安全的。但是限制访问是一种合理的模式。

在下面的代码片段中,
System.PrivateEmployee
在系统类之外不可见。因此,
privateMethod
实际上是私有的,只能从
系统
类中调用。由于
System.PrivateEmployee
扩展了
System.PublicEmployee
,因此它可以在
System
类之外作为
System.PublicEmployee

public class System
{
      public static interface PublicEmployee { void publicMethod ( ) ; }
      private static interface PrivateEmployee extends PublicEmployee { void privateMethod ( ) ; }
}

使用仅对其他服务类可用的内部类:

public class Employee
{
  static {
    LineStructureService.registerEmployeeHelper(new EmployeeHelper() {
      @Override
      public void setLineManager(Employee emp, Object foo) {
        emp.setLineManager(foo);
      }
    });
  }

  public static void init() {}

  private void setLineManager(Object foo) { }  
}

public class LineStructureService
{
  private static volatile EmployeeHelper _helper;

  static {
    // ensure that Employee class is loaded and helper registered
    Employee.init();
  }

  public static synchronized void registerEmployeeHelper(EmployeeHelper helper) {
    _helper = helper;
  }

  public void doSomething(Employee emp)
  {
    // now this class can call setLineManager on Employee
    _helper.setLineManager(emp, blah);
  }

  public interface EmployeeHelper {
    public void setLineManager(Employee emp, Object foo);
  }
}

您可以使用AOP(例如AspectJ或CDI)拦截对setLineManager()的调用;如果调用方是updateLineStructureService(),则调用该方法;如果不是什么都不做,或者引发异常或其他任何情况。

java就是java;你被它提供的设施困住了。如果没有令人发指的背信弃义,答案是否定的。包级访问的想法无论如何都没有意义,因为同一个包中的任何其他东西都可以访问,而不仅仅是您的服务。任何其他类(假设类加载器允许)也可以使用反射。这只是一个想法。您可以将其设置为受保护,并在UpdateLineStructureService类中创建一个扩展Employee的内部类。@Tom包中的其他所有类都可以看到受保护的方法。@Pablo true,但它仍然比public好。。。但仍然相当丑陋:/另请参见:我提到的“令人发指的背叛”伎俩之一;绝对有效,绝对令人发指;)是的,这是个坏主意,我同意。我一生中用过一次,我有一个反复出现的梦想,从那以后,我的老板用一只黑猩猩取代我。不幸的是,它是有效的。而且,这将是非常缓慢的!与我的想法相似,但有点干净。美好的