Java EE: Bind some interceptor annotations to a single one - java

First of all: I want to use Java EE not Spring!
I have some self defined annotations which are acting as interceptor bindings. I use the annotations on my methods like this:
#Logged
#Secured
#RequestParsed
#ResultHandled
public void doSomething() {
// ...
}
For some methods I want to use a single of these annotations but most methods I want to use like this:
#FunctionMethod
public void doSomething() {
// ...
}
Can I bundle these set of annotations to a single one? I cannot write the code in a single interceptor because for some methods I want to use them seperately too.
I know that there is a #Stereotype definition possible, but as far as I know, this is used to define a whole class not a single method.

With help of some well-known search engine I found the solution in the documentation of JBoss Weld (Chapter 9.6 Interceptor binding with inheritance)
I can use an interceptor binding interface which is inherited from other interceptor bindings. It will look like this:
#InterceptorBinding
#Target({ ElementType.METHOD, ElementType.TYPE })
#Retention(RetentionPolicy.RUNTIME)
#Logged
#Secured
#RequestParsed
#ResultHandled
public #interface FunctionMethod {
// clean and empty
}
Now I can use the new interceptor binding on the bean method and all of the interceptors will be called:
#FunctionMethod
public void doSomething() {
// ...
}

I would say, that you are on the right pass with a stereotype.
It's right, that the examples one finds and also the official Java EE 6 Tutorial only uses it on a class as an example (e.g. #Model), but you may as well declare #TYPE(MEHOD) in your custom annotation and then I assume that it works.

Related

Using class level #PreAuthorized annotations alongside method level #PreAuthorzied annotations

I am trying to get a #PreAuthorized annotation on a controller class to work in conjunction with a #PreAuthorized annotation on methods (endpoints) of the same class.
The overview of the class looks something like this:
#RestController
#RequestMapping("/api")
#PreAuthorized("hasRole('CLASS_LEVEL_ROLE')")
public class foo {
#GetMapping("/test")
#PreAuthorized("hasRole('METHOD_LEVEL_ROLE')")
#Timed
public ResponseEntity<String> bar() {
return ResponseEntity.ok().body("entered method successfully");
}
}
Currently what is happening is only the method level annotation is being taken into account.
Ideally what would happen is only users with role 'CLASS_LEVEL_ROLE' and 'METHOD_LEVEL_ROLE' would be allowed access to bar().
I'm aware I could use
#PreAuthorized("hasRole('CLASS_LEVEL_ROLE') and hasRole('METHOD_LEVEL_ROLE')")
but I have some controllers where all endpoints would have to have the same 'CLASS_LEVEL_ROLE' and it would be more convenient to have a generalized class annotation.
#PreAuthorize allows a class level annotation. The way it is supposed to work is that if a method level annotation exists, it will override the class level annotation. You can't do a union of both. So a class level annotation can be seen as a fallback when a method level annotation is not present.

Java annotation negation logic

Is it possible to create a Java annotation with reverse / inverse / negation logic.
For e.g., I created a filter in Javax:
#Provider
#AuthBinding
public class AuthServerFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {...}
And created AuthBinding annotation as:
#NameBinding
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.TYPE})
public #interface AuthBinding {
}
So , the above filter will be triggered for only the rest resources with the annotation #AuthBinding.
Is it possible to create an annotation, so that above filter is applied on all the rest resources except the ones which have annotation.
Such frameworks work by explicitly marking "things". The framework scans classes, objects, methods for annotations, and then runs the corresponding code.
There is no notion of "if an annotation X isn't given, then do this or that, depending on X".
And not it is not only technology here. It is a bad design idea! Especially in such a REST resource context, your readers expect that looking at the resource tells them all they need to know about it.
Well, one option exists: you can of of course configure your own filters or interceptors. And those could check if a selected resource does have or not have a specific annotation on it before doing this or that.

Intercepting aspect for custom annotion

I am writing a library/sdk which can intercept any methods which are annotated with a custom annotation #Monitor.
The code works somewhat like this
#Monitor
public void methodA(String test)
And the aspect which intercepts this has this pointcut expression
#After("execution(#com.packageA.Monitor * *(..))")
public void intercept(final JoinPoint joinPoint){
...}
This code works fine when I describe the aspect in the same package as the methodA. However if I create a separate library and define the aspect in that its not able to intercept the methodA . Any help?
EDIT
In response to #Bond's comment
#Component
#Target(value = {ElementType.METHOD, ElementType.TYPE})
#Retention(value = RetentionPolicy.RUNTIME)
public #interface Monitor {
}
Spring versions:
spring-context - 4.1.7.Release
aspectj - 1.6.5
The crux of the problem is that the annotation wont be used in the same project. After compilation it will be used in a different project all together.
EDIT2
The 2nd project i.e the one from which this aspect should be intercepting is compiled using aspectj maven plugin
You need to update the pointcut to #annotation(com.x.y.z.Monitor). (correct the package name accordingly)
Thus your aspect should look something like below
#After("#annotation(com.x.y.z.Monitor)")
public void intercept(final JoinPoint joinPoint){
...
}
Have a look at examples for reference about various pointcut expressions available. Also read this in case advise accepts argument(s)

Customised annotation in spring

I have seen few examples where customized annotations were used. example
#SimpleAnnotation
class SampleBean {
#SimpleAnnotation
public String getName() {
return "AAA";
}
public void setName(String name) {
}
public int getHeight() {
return 201;
}
}
#Target( { ElementType.METHOD, ElementType.TYPE })
#Retention(RetentionPolicy.RUNTIME)
#interface SimpleAnnotation {
}
Can anyone tell why we use this?
Spring supports for many Annotation the concept of "meta-annotation". (I am not sure if it is for all.)
This mean that you can build your own annotation and annotate the annotation with one of springs "core" annotations.
For example:
#Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE })
#Retention(RetentionPolicy.RUNTIME)
#Service
public #interface MyService {
}
Then you can use this annotation instead of #Service. (Btw: #Service, #Repository, #Controller use the same technique to "inherit" from #Component)
One example that make heavy use of this is "inherit" from #Qualifier.
For an example and some explanation have a look at Spring Reference Chapter: 3.9.3 Fine-tuning annotation-based autowiring with qualifiers (The Example with #Genre is at the end of the chapter.)
One very usefull construct that can be done with that technique is, that it enables you to combine several Annotations to a (in your use case) more meaning full. So instead of writing at every class of some type allways the same two annotations, for example: #Service and #Qualifiyer("someting") (the org.springframework.beans.factory.annotation.Qualifier). You can create your custom annotation that is annotated with this two annotations, and then use in your beans only this one custom annotation. (#See Avoid Spring Annotation Code Smell Use Spring 3 Custom Annotations)
If you want to see how powerfull this technique can be use, you can have a look at Context and Dependency Injection Framework.
Question from the comment:
The #interface also has some variables defined inside it, what does that signify?
The Annotations (defined by #Interface) work a bit like beans. This Fields are the properties that can/must be define if you use the annotations. The values can be later on be read via reflection API.
For example the #Controller Annotation in Spring:
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Component
public #interface Controller {
String value() default "";
}
The field with name value is that field that can be used without explicit name it: (#Controller("myUrl") is the same #Controller(value="myUrl"))
You can create your own meta-annotations that collect several other Spring annotations to reduce meta-boilerplate in your code:
#Service
#Scope(value = "prototype")
#Transactional(readOnly = true, rollbackFor = RuntimeException.class)
public #interface ReadOnlyService {}
And then you can simply write:
#ReadOnlyService
public class RoleService {
}
Spring will find the #ReadOnlyService and semantically replace it with:
#Service
#Scope(value = "prototype")
#Transactional(readOnly = true, rollbackFor = RuntimeException.class)
public class RoleService {
}
Of course having custom annotations pays of when you have tons of services annotated with the same set of Spring annotations that can be replaced with one, well named annotation.
Examples taken from: Avoid Spring Annotation Code Smell: Use Spring 3 Custom Annotations
Custom annotations do not do anything on their own. They are simple markers in code. Their real power comes from tools that look for specific annotations. Like some of the other answers mention, Spring has several uses for annotations and now mechanisms for defining your own component types. Pretty neat. Another example, a few weeks ago I used AOP and a few custom annotations to provide simple method level result caching. Now that I have the caching engine in place, and the appropriate AOP hooks defined, if I want to cache a method, I simply add that annotation. Some people simply use the annotations as fancy metadata to improve readability.
At the end of the day, they are a fairly simple tool that you can use for a great number of things.
The best part of using custom annotations is that you don't have to make any configuration, Spring will auto detect that these beans are service components and everything will work fine. Custom Annotations are a very small feature added in Spring but are very useful.For details take a look at this
http://java.dzone.com/articles/avoid-spring-annotation-code-smell-use-spring3-custom-annotations
Two options:
you need the #Component annotation on your custom annotation. That way you can use your custom annotation to mark classes as beans. In addition, you can add a default scope and other meta-information
qualifiers - you can use qualifier annotations (annotated with the #Qualifier meta-annotation) to distinguish between implementations of the same interface.
A common pattern is also to use annotations in AOP pointcuts. Not specifically Spring, but often employed when making use of Spring AOP.

Method Parameter Validation with JSR-303

Is JSR-303 also intended for method parameter validation?
If so, is there any example on the web? The biggest challenge I'm facing is how to get a validator within each method. With Spring 3, doesn't it mean that I'd have to inject virtually every class with a LocalValidatorFactoryBean?
Thanks!
Method level validation will be supported in the upcoming version 4.2 of JSR 303's reference implementation Hibernate Validator.
As pointed out in the previous answer this will allow constraint annotations (built-in as well as custom defined types) to be specified at method parameters and return values to specify pre- and post-conditions for a method's invocation.
Note that HV will only deal with the actual validation of method calls not with triggering such a validation. Validation invocation could be done using AOP or other method interception facilities such as JDK's dynamic proxies.
The JIRA issue for this is HV-347 [1], so you might want to add yourself as watcher to this issue.
[1] http://opensource.atlassian.com/projects/hibernate/browse/HV-347
The javadocs for each of the JSR 303 annotations tells the following:
#Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})
See, PARAMETER is there. So, yes, it's technically possible.
Here's an example:
public void method(#NotNull String parameter) {
// ...
}
I'm however not sure how that integrates with Spring since I don't use it. You could just give it a try.
In Spring 3.1.0 you can use #Validated annotation to activate validation on a pojo.
Create an interface for the pojo class an put this annotation over it, then add your validation annotations in the methods definitions. ( the interface is required because Spring will create a proxy class using the interface as definition )
#Validated
public interface PojoClass {
public #NotNull String doSomething(#NotEmpty String input);
}
your pojo :
public class PojoClassImpl implements PojoClass {
public String doSomething(String input) {
return "";
}
}
Starting from a standard spring web application with active validation, remember to add in your spring configuration this bean declaration:
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
This sounds like a use case for AOP (AspectJ). Write a pointcut for methods that are annotated with javax.validation.constraints.*, inject a validator into the aspect (probably using Spring) and use a #Before or #Around advice to perform the validation before method execution.
Read AspectJ in Action for reference.
You can use jcabi-aspects (I'm a developer), which integrates JSR 303 with AspectJ. Actual validation is done by one of JSR 303 implementations, which you will have to add to class path, like Hibernate Validator, or Apache BVal.

Categories