I'm playing with interceptors and annotations but I'm pretty confused and I cannot find a extensive tutorial.
Actually I don't understand the difference between this:
#Inherited
#InterceptorBinding
#Target({TYPE, METHOD})
#Retention(RUNTIME)
public #interface MyCustomAnnotation {}
and this:
#Inherited
#Target({TYPE, METHOD})
#Retention(RUNTIME)
public #interface MyCustomAnnotation {}
what #InterceptorBinding do? Why use it and why not?
I'm searching for some good how-tos with examples about annotations and interceptors, covering different use cases, but I've found documentation about very basic usages or some cryptic code (at least for me) without any explanation, so thank you if you can give me some pointer.
Consider interceptor declaration:
#Inherited
#InterceptorBinding
#Retention(RUNTIME)
#Target({METHOD, TYPE})
public #interface Logged {
}
#InterceptorBinding is just an indicator that used to bind annotations to specific interceptor.
Along with an interceptor, an application defines one or more interceptor binding types, which are annotations that associate an interceptor with target beans or methods. For example, the billpayment example contains an interceptor binding type named #Logged and an interceptor named LoggedInterceptor.
#Inherited is used to allow this annotation down by class hierarchy.
An interceptor binding also has the java.lang.annotation.Inherited annotation, to specify that the annotation can be inherited from superclasses. The #Inherited annotation also applies to custom scopes (not discussed in this tutorial), but does not apply to qualifiers.
Also take a look at documentation .
Related
Is it correct to put #Secured annotations on interface methods or on methods within classes implementing the interface? Are there any recommendations for this?
When I dig into the class defining the #Secured annotation, I can see that it has the #Inherited annotation set:
#Target({ ElementType.METHOD, ElementType.TYPE })
#Retention(RetentionPolicy.RUNTIME)
#Inherited
#Documented
public #interface Secured {
/**
* Returns the list of security configuration attributes (e.g. ROLE_USER, ROLE_ADMIN).
*
* #return String[] The secure method attributes
*/
public String[]value();
}
Having read this answer, I guess I can set the #Secured annotation on the interface to consistently enforce authorization over all implementations of the interface.
In your provided link said, #Transactional is also #Inherited. Lets break down each part of them.
As per spring's developers recommended that use #Transactional annotation with concrete class.
You can use #Transactional annotation in interface or a method inside the interface. You can think this will work as you expected if you used interface-based-proxies. Annotation that is not inherited refers that if you are using class-based-proxies then probably transaction attribute are not applied to that interface. So the ultimate object can not covered or wrapped by transactional attribute.
If so, #Secured annotation is #Inherited then this can be used both in interface and its implementation class.
From spring docs:
The Secured annotation is used to define a list of security configuration attributes for business methods.
For example:
#Secured({ "ROLE_USER" })
public void create(Contact contact);
#Secured({ "ROLE_USER", "ROLE_ADMIN" })
public void update(Contact contact);
#Secured({ "ROLE_ADMIN" })
public void delete(Contact contact);
So In the bottom line, you may have multiple implementations for an interface. So, keeping your #Secured annotation in interface makes sense.
Is it possible to make pointcut using Spring AOP for methods and type having annotation which was annotated with some annotation.
Here's my custom annotation:
#AccessRestriction
#Target({ElementType.METHOD, ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
public #interface HasPermission {
}
It annotated with this annotation:
#Target({ElementType.ANNOTATION_TYPE})
#Retention(RetentionPolicy.RUNTIME)
public #interface AccessRestriction {
}
So is it possible to create point cut which will handle all methods which are annotated with any annotation annotated with AccessRestriction.
I found solution.
I made such pointcut:
within(#(#test.security.access.AccessRestriction *) *) ||
execution(#(#test.security.access.AccessRestriction *) * *(..))
Below is source code of For Component Interface
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
#Documented
public #interface Component {
and for Spring Controller annotation is as below
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Component
public #interface Controller {
Why #Component is added in Controller annotation ? What is its purpose ? What if I remove this line ?
I am clear about below annotation types which are used to create custom annotations.
#Documented Whether to put the annotation in Javadocs
#Retention When the annotation is needed
#Target Places the annotation can go
#Inherited Whether subclasses get the annotation
#Controller is a #Component (just like #Service, #Repository, #Endpoint etc.).
The #Component is used as a meta-annotation here so that it can be picked-up using component-scanning. Next to that the #Controller is a special component which will have some added functionality (Spring MVC takes care of that). If you remove the #Component annotation component-scan will not be able to detect it anymore.
You can also create your own #Component based annotations by simply creating your own annotation and putting #Component on it.
#Component is a generic stereotype for any Spring-managed component. #Repository, #Service, and #Controller are specializations of #Component for more specific use cases, for example, in the persistence, service, and presentation layers, respectively.
Read this answer
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.
I have a set of beans that are characterized by two properties. They are basically serializers for different classes and for different purposes.
For example, there may be an Order serializer for local log, Order serializer for logging webservice call, Customer serializer for tracking URL and Customer serializer for tracking URL.
This is why I'd like to use two #Qualifier annotations like this:
#Autowired
#Qualifier("order")
#Qualifier("url")
private Serializer<Order> orderSerializer;
Unfortunately, compiler complains about duplicate annotations in this case. Are there any workarounds or alternative solutions to this problem?
I understand that this question is rather old, but this is something you should be able to accomplish since Spring 2.5.
You can create your own annotations that are themselves annotated with #Qualifier, a form of annotation composition. Spring will honor these qualifiers as though they are their own.
Consider these two annotation types, named similarly to your example:
#Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Qualifier
public #interface MyOrderQualifier {
}
#Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Qualifier
public #interface MyUrlQualifier {
}
You should be able to use both of these annotations on your field, since they are independent annotations.
#Autowired
#MyOrderQualifier
#MyUrlQualifier
private Serializer<Order> orderSerializer;
Here is a link to the Spring 2.5 reference documentation explaining this process. Please note that it is for Spring 2.5 and may be out of date with regards to more recent versions of Spring.
#Qualifier("order-url")
and respectively name your component order-url
#Component("order-url")
Of course I don't know all the details, but this issue is more like a task for Decorator pattern. Probably, you may bound this in a Spring config if it's necessary.
Or, I agree with Bozho here, you could use some name conventions across you Spring beans, so that bean name could reflect its responsibility and area of application.