如何在Java类中创建只能从一个其他类访问的方法
我想知道是否有人有一个模式可以帮助我实现以下目标: 我们有一个名为Employee的JPA实体,上面有一个setLineManager方法。我们还有一个单独的updateLineStructureService,它是一个Spring管理的服务bean。我们希望尝试并确保此setLineManager方法只能从updateLineStructureService调用,而不能直接从任何其他类调用 是否有一种方法允许服务访问此方法而不将其公开给任何其他类?我知道我可以授予方法包级别的访问权,并将服务与员工放在同一个包中,但这不适合我们的包结构,因此我不希望这样做。我也知道,我可以将该方法设置为私有,并在这个地方通过反射来访问它,但我一点也不喜欢这种解决方案如何在Java类中创建只能从一个其他类访问的方法,java,spring,Java,Spring,我想知道是否有人有一个模式可以帮助我实现以下目标: 我们有一个名为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好。。。但仍然相当丑陋:/另请参见:我提到的“令人发指的背叛”伎俩之一;绝对有效,绝对令人发指;)是的,这是个坏主意,我同意。我一生中用过一次,我有一个反复出现的梦想,从那以后,我的老板用一只黑猩猩取代我。不幸的是,它是有效的。而且,这将是非常缓慢的!与我的想法相似,但有点干净。美好的