Advanced Java Repeatable Annotations + Reflection: Role-Based Method Execution Framework

Build a real-world style framework using repeatable annotations, reflection, and role-based method execution similar to Spring Security.

Advanced Example: Role-Based Execution System

We will build a mini framework where methods execute only if the user has the required role. Multiple roles are supported using repeatable annotations.

Step 1: Create Repeatable Annotation

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(Roles.class)
@interface Role {
    String value();
}

Step 2: Container Annotation

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Roles {
    Role[] value();
}

Step 3: Service Class

class UserService {

    @Role("ADMIN")
    @Role("MANAGER")
    public void deleteUser() {
        System.out.println("User deleted");
    }

    @Role("USER")
    public void viewProfile() {
        System.out.println("Viewing profile");
    }
}

Step 4: Framework Engine (Reflection Logic)

import java.lang.reflect.*;
import java.util.*;

class FrameworkEngine {

    public static void execute(Object obj, String role) throws Exception {

        Method[] methods = obj.getClass().getDeclaredMethods();

        for (Method m : methods) {
            Role[] roles = m.getAnnotationsByType(Role.class);

            if (roles.length > 0) {
                for (Role r : roles) {
                    if (r.value().equals(role)) {
                        System.out.println("Access granted for role: " + role);
                        m.invoke(obj);
                        return;
                    }
                }
                System.out.println("Access denied for role: " + role);
            }
        }
    }
}

Step 5: Main Class

public class Main {
    public static void main(String[] args) throws Exception {

        UserService service = new UserService();

        FrameworkEngine.execute(service, "ADMIN");
        FrameworkEngine.execute(service, "USER");
        FrameworkEngine.execute(service, "GUEST");
    }
}

Output

Access granted for role: ADMIN
User deleted
Access granted for role: USER
Viewing profile
Access denied for role: GUEST

What This Demonstrates

  • Repeatable annotations for multiple roles
  • Reflection to scan methods
  • Dynamic method execution
  • Basic security layer implementation
  • Framework-like behavior

How This Relates to Spring

  • @PreAuthorize → Role-based access
  • @Autowired → Dependency injection
  • @Transactional → Method interception
  • Spring uses reflection + proxies internally

Advanced Twist (Interview Level)

Modify the framework to:

  • Execute multiple matching methods
  • Add logging annotation (@Log)
  • Cache reflection results (performance optimization)
  • Support class-level annotations
  • Add exception handling layer

Final Insight

This is exactly how modern frameworks work internally: annotations declare intent, reflection processes them, and the framework executes logic dynamically.