Say, as it is popular now, you want to have possibility of either static (annotation-based) or dynamic (xml/db-based) configuration of your piece of programming mastership. For instance, your application should support some basic privilege-based security, so, we’ll define @Privilege annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Privilege {
String code();
}
And a class using it:
public class AccountController { … }
Abstracting from the details of implementation, the handling of the annotation might look like this:
public Object intercept(User user, Object controller) {
annotations.Privilege priv = getPrivilege(controller);
user.hasPrivilege(priv.code());
}
protected annotations.Privilege getPrivilege(Object controller) {
return controller.getClass().getAnnotation(annotations.Privilege.class);
}
}
Now, we want to be able to configure another controller, OrderController, in a more dynamic way, e.g. by loading the following configuration:
<privilege>manage.account</privilege>
</controller>
So we need to have an object representation for privilege:
and a privilege-aware controller:
public SecuredController(Privilege priv) { this.privilege = priv; }
public Privilege getPrivilege() { return privilege; }
}
public class OrderController extends SecuredController {
public OrderController(Privilege priv) { super(priv); }
}
See how Privilege and @Privilege are similar? (yeh, I tried to make it obvious
)… And in the declaration of annotations.Privilege there is an interface keyword… hm, does it mean we can implement the annotation? Why not! So here we go:
And the last stroke is to slightly modify SecurityInterceptor‘s getPrivilege method (of course, being developers of good manners, we shall follow Open-Close Principle):
protected annotations.Privilege getPrivilege(Object controller) {
return (controller instanceof SecuredController) ?
((SecuredController) controller).getPrivilege() :
controller.getClass().getAnnotation(annotations.Privilege.class);
}
}
Note: the java compiler will threaten you with “Annotation is used as super interface” warning, but you should remain brave and confident!
Moral of the story: reuse code and reduce your maintenance effort!
Feel free to comment, criticise and share your feelings.
Tags: annotations, core java
