0

I want to have some @Component beans which should be only called from @Service beans and no other bean. How can I enforce it? I don't want to change maven packaging. What about requiring running transaction? But it is only runtime not compile time check.

Zveratko
  • 2,663
  • 6
  • 35
  • 64

1 Answers1

1

Add an aspect to intercept the service methods calls.

@Around("execution(* MyComponent)")
public void wrapAround(ProceedingJoinPoint joinPoint) throws Throwable 
{
    joinPoint.proceed(); 
}

See more here

and then check caller class

public class KDebug {
    public static String getCallerClassName() { 
        StackTraceElement[] stElements = Thread.currentThread().getStackTrace();
        for (int i=1; i<stElements.length; i++) {
            StackTraceElement ste = stElements[i];
            if (!ste.getClassName().equals(KDebug.class.getName()) && ste.getClassName().indexOf("java.lang.Thread")!=0) {
                return ste.getClassName();
            }
        }
        return null;
     }
}

Got from here

Check whether the caller class has annotation

for (Annotation annotation : Caller.class.getAnnotations()) {

and find whether the caller has @Service annotation. If not throw an exception

StanislavL
  • 56,971
  • 9
  • 68
  • 98
  • Nice, but still only runtime solution.Anything that can be done for compile time check? – Zveratko Jun 27 '17 at 12:25
  • I doubt it's possible to do compile time check. Annotation is just a marker and indirect calls are possible. – StanislavL Jun 27 '17 at 12:29
  • One way, although little bit complicated is to create some compiler annotation processor. Maybe I have to wait for Java 9 modules support. – Zveratko Jun 28 '17 at 04:55