Is it possible to use multiple #Qualifier annotation in Spring? - java

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.

Related

Spring boot - is there a way to disable AOP for a given profile?

I have been having issues with AOP when running the build and/or running tests. I tried to annotate the #Aspect class with #Profile("local", "war") to make sure that aspect is only accessible to the "local" and "war" profiles, but a scenario might incur when we need to add that aspect support to another profile. And we prefer not to have this hard-coded there.
Is there a clean way to forbid, for instance, the "test" profile to access a given aspect class?
Assuming, aspects are treated as beans in spring:
If its only about "create aspect only if not in profile test", then you can merely go with:
#Profile("!test")
If you want a more sophisticated condition, then keep reading:
Spring profiles were introduced in Spring 3.x but in 4.x the were rewritten with more flexible conditionals.
Take a look at #Profile source code:
#Target({ElementType.TYPE, ElementType.METHOD})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Conditional(ProfileCondition.class)
public #interface Profile {
/**
* The set of profiles for which the annotated component should be registered.
*/
String[] value();
}
Note the #Conditional with ProfileCondition as an implementation of "evaluation" logic.
This class's implementation is pretty straightforward.
You can create your custom annotation like a profile that will call a similar evaluation logic.

Java interceptors, confused about #InterceptorBinding

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 .

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.

What is javax.inject.Named annotation supposed to be used for?

I am trying to understand the javax.inject package and I am not clear what the javax.inject.Named annotation is supposed to be used for. The Javadoc does not explain the the idea behind it.
Javadoc is at http://download.oracle.com/javaee/6/api/javax/inject/Named.html
I am using Spring 3.0 to write some sample programs, by putting #Named on a bean it seems to add it to the bean factory but the Javadoc description is so light I can't tell if that is the standard behavior or Spring specific behavior.
My questions are:
What is the difference between #Named and #Qualifier
How are you supposed to tell the Runtime system a class should be injectable in other classes what's the annotation for that? The equivalent of #Component in Spring?
Update 1 there is an excellent explanation of #Named and #Qualifier at Nice article about #Named and #Qualifier https://dzone.com/articles/java-ee6-cdi-named-components thanks #xmedeko for linking to it the comment below.
Use #Named to differentiate between different objects of the same type bound in the same scope.
#Named("maxWaitTime")
public long maxWaitTimeMs;
#Named("minWaitTime")
public long minWaitTimeMs;
Without the #Named qualifier, the injector would not know which long to bind to which variable.
If you want to create annotations that act like #Named, use the #Qualifier annotation when creating them.
If you look at #Named, it is itself annotated with #Qualifier.
#Inject instead of Spring’s #Autowired to inject a bean.
#Named instead of Spring’s #Component to declare a bean.
Those JSR-330 standard annotations are scanned and retrieved the same way as Spring annotation (as long as the following jar is in your classpath)
Regarding #2, according to the JSR-330 spec:
This package provides dependency
injection annotations that enable
portable classes, but it leaves
external dependency configuration up
to the injector implementation.
So it's up to the provider to determine which objects are available for injection. In the case of Spring it is all Spring beans. And any class annotated with JSR-330 annotations are automatically added as Spring beans when using an AnnotationConfigApplicationContext.
The primary role of the #Named annotation is to define a bean for the purpose of resolving EL statements within the application, usually through JSF EL resolvers. Injection can be performed using names but this was not how injection in CDI was meant to work since CDI gives us a much richer way to express injection points and the beans to be injected into them.

Custom Spring sterotype annotation with scope of prototype?

I created a custom sterotype #Action, and Spring has managed to detect it in the package scan I configured in the configurations.
The next step I would like to do is to tell Spring that all classes with #Action should be created with prototype, instead of Singleton.
My #Action interface is as follows:
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Component
public #interface Action {
}
I tried to mark it with #Scope("prototype") but that does not seem to help.
Is what I desire possible?
Kent
The context:component-scan can be configured with a custom scope-resolver, which implements org.springframework.context.annotation.ScopeMetadataResolver.
I created a custom scope-resolver that not only checks the bean for a #Scope annotation (with the default resolver of org.springframework.context.annotation.AnnotationScopeMetadataResolver), but looks up annotations of annotations too (recursively).
One thing to note though, that looking up annotations recursively might go into an endless loop, as java.lang.annotation.Documented is annotated with java.lang.annotation.Documented. Best to maintain a table that indicates which annotation has been looked up already.
Unfortunately not with spring 2.5.X. Your #Component-annotation describes the role of the bean while the scope is a separate axis, so a role and scope descriptor typically have to be applied separately to the implementation class. When viewed in this way it makes some sense (edit: at least it did so for a few seconds, anyway)
I don't know how this will change i spring 3.x, which is not too far away. There seems to be some room for improvement.

Categories