下面是一个使用自定义注解的场景:实现一个简单的权限检查系统。在这个系统中,我们定义一个注解@RequiresRole
,它用于标记方法需要哪些用户角色才能访问。然后,我们通过AOP拦截器来检查调用方法的用户是否具有相应的角色。
第一步:定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiresRole {
String value();
}
第二步:实现拦截器
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.matcher.Matchers;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class RoleCheckingInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
RequiresRole requiresRole = invocation.getMethod().getAnnotation(RequiresRole.class);
if (requiresRole != null) {
if (!currentUserHasRole(requiresRole.value())) {
throw new SecurityException("User does not have the required role: " + requiresRole.value());
}
}
return invocation.proceed();
}
private boolean currentUserHasRole(String role) {
// 模拟用户角色检查
// 在实际应用中,这里应该是检查当前用户的权限
return "ADMIN".equals(role); // 假设当前用户只有ADMIN角色
}
}
第三步:配置Guice模块
public class SecurityModule extends AbstractModule {
@Override
protected void configure() {
MethodInterceptor interceptor = new RoleCheckingInterceptor();
bindInterceptor(Matchers.any(), Matchers.annotatedWith(RequiresRole.class), interceptor);
}
}
第四步:使用注解
public class SecureService {
@RequiresRole("ADMIN")
public void adminOnlyOperation() {
System.out.println("Executing admin-only operation.");
}
@RequiresRole("USER")
public void userOperation() {
System.out.println("Executing user operation.");
}
}
第五步:启动应用并测试
public class Main {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new SecurityModule());
SecureService secureService = injector.getInstance(SecureService.class);
try {
secureService.adminOnlyOperation(); // 应该成功,因为模拟用户是ADMIN
} catch (SecurityException e) {
System.err.println(e.getMessage());
}
try {
secureService.userOperation(); // 应该失败,因为模拟用户不是USER
} catch (SecurityException e) {
System.err.println(e.getMessage());
}
}
}
执行main
方法时,adminOnlyOperation
将成功执行,因为我们假设当前用户具有ADMIN
角色。而userOperation
将抛出SecurityException
,因为用户没有USER
角色。
注意事项
- 确保Guice的AOP代理可以拦截到需要检查权限的方法。这通常意味着方法是在通过Guice注入的对象上调用的。
- 注解
@RequiresRole
在运行时可用,因为它的@Retention
策略是RetentionPolicy.RUNTIME
。 - 拦截器
RoleCheckingInterceptor
中的currentUserHasRole
方法需要根据实际情况实现,以检查当前用户是否具有指定的角色。 - 为了实现真正的安全性,应该与现有的安全框架(如Spring Security)集成,或者实现完整的用户身份验证和授权逻辑。
- 在生产环境中,错误处理应该更加精细,并且应该记录必要的日志信息。