如何在同一个 class 中强制调用 getter
How can I make getter's call mandatory in the same class
我有这个代码:
我如何在 getAll 方法中强制使用 getService() 方法,这意味着如果我直接调用 service.findAll()
编译失败?
是否可以创建一个注释来禁止直接使用该字段?
@Named
@Profile("default")
public class AlfrescoVersionServiceImpl {
@Inject
//Request Scope service
private AlfrescoService service;
@Resource
private WebServiceContext webServiceContext;
public List<Fichier> getAll(){
return getService().findAll();
}
public AlfrescoService getService(){
service.setEnPointAdress("--");
if(webServiceContext.isUserInRole(role)){
service.setRole("--");
}
}
}
提前感谢您的回复。
在 findAll()
中,您可以使用 Thread.getStackTrace()
检查当前堆栈跟踪,并确保之前的 StackTraceElement
是您想要的 class 和方法:
public List<Fichier> findAll() {
StackTraceElement[] stack = Thread.getStackTrace();
if(stack.length > 1) {
// stack[0] is ourselves, stack[1] is who called us
if(stack[1].getClassName().equals(...) && stack[1].getMethodName().equals(...) {
// execute the business logic
}
}
}
请注意以下几点:
- 这是一个运行时检查,因此调用
findAll()
的方法不会在编译时被标记。
- 根据JavaDocs,某些SecurityManagers 可能不允许
getStackTrace()
方法,并且某些VM 可能会在极少数情况下忽略堆栈帧。
- 如果您对每个请求都这样做,这可能不会有效。
- 如果服务是 Spring bean,您可能需要通过代理 classes 进行排序以找到真正的调用者(即
findAll()
之前的前一个堆栈帧可能是 spring 生成的代理 class).
另一种方法是使用面向方面的框架。例如,Spring AOP 有 ControlFlowPointcut 可用于匹配调用者姓名、class 和包。这种方法更具声明性,
但依赖于额外的库。
您可以将 service
字段移动到超级 class 中,并声明它 private
以防止子 class 访问它,同时保留 getService()
protected
.
或者,您可以在 @Produces
方法中配置 AlfrescoService
,这样每个要求注入 AlfrescoService
的人都会得到一个已经配置好的实例。
我有这个代码:
我如何在 getAll 方法中强制使用 getService() 方法,这意味着如果我直接调用 service.findAll()
编译失败?
是否可以创建一个注释来禁止直接使用该字段?
@Named
@Profile("default")
public class AlfrescoVersionServiceImpl {
@Inject
//Request Scope service
private AlfrescoService service;
@Resource
private WebServiceContext webServiceContext;
public List<Fichier> getAll(){
return getService().findAll();
}
public AlfrescoService getService(){
service.setEnPointAdress("--");
if(webServiceContext.isUserInRole(role)){
service.setRole("--");
}
}
}
提前感谢您的回复。
在 findAll()
中,您可以使用 Thread.getStackTrace()
检查当前堆栈跟踪,并确保之前的 StackTraceElement
是您想要的 class 和方法:
public List<Fichier> findAll() {
StackTraceElement[] stack = Thread.getStackTrace();
if(stack.length > 1) {
// stack[0] is ourselves, stack[1] is who called us
if(stack[1].getClassName().equals(...) && stack[1].getMethodName().equals(...) {
// execute the business logic
}
}
}
请注意以下几点:
- 这是一个运行时检查,因此调用
findAll()
的方法不会在编译时被标记。 - 根据JavaDocs,某些SecurityManagers 可能不允许
getStackTrace()
方法,并且某些VM 可能会在极少数情况下忽略堆栈帧。 - 如果您对每个请求都这样做,这可能不会有效。
- 如果服务是 Spring bean,您可能需要通过代理 classes 进行排序以找到真正的调用者(即
findAll()
之前的前一个堆栈帧可能是 spring 生成的代理 class).
另一种方法是使用面向方面的框架。例如,Spring AOP 有 ControlFlowPointcut 可用于匹配调用者姓名、class 和包。这种方法更具声明性, 但依赖于额外的库。
您可以将 service
字段移动到超级 class 中,并声明它 private
以防止子 class 访问它,同时保留 getService()
protected
.
或者,您可以在 @Produces
方法中配置 AlfrescoService
,这样每个要求注入 AlfrescoService
的人都会得到一个已经配置好的实例。