I'm using spring to build Controller -> Service -> Repository architecture.
However, others developer can autowired repository in controller or anywhere.
I don't want others to violate the 3 layer architecture.
So, I using aspectj to check caller for Repository.
if caller is Service -> pass;
else throw exception.
@Aspect
public class ModelAdvice {
private Pattern pattern = Pattern.compile("^demo\\.services\\..*");
@Before("execution(* demo.repositories..*Repository.*(..))")
public void protectRepositories(JoinPoint joinPoint) {
StackTraceElement[] stElements = Thread.currentThread().getStackTrace();
for (StackTraceElement element : stElements) {
Matcher matcher = pattern.matcher(element.getClassName());
if (matcher.matches()) {
return;
}
}
throw new RuntimeException("security violation!");
}
}
It work, but ugly and may be slow.
Is spring have some elegant way to do this?