I am using Java1.7 and spring3.
I have below classes.
MyInterface.java
public interface MyInterface{
String getResult();
}
MyInterfaceImpl.java
public class MyInterfaceImpl implements MyInterface{
#MyCustomAnnotation
public String getResult(){
//some logic
}
}
I annotated method in Impl class. Is it good practice to annotate methods in implementation class? Or do i need to annotate methods in the interface itself?
Thanks!
Classes don't inherit the annotation from interfaces, so you should be really careful using annotations on interfaces.
Here is an example of what can happen if you are not careful:
http://kim.saabye-pedersen.org/2013/05/spring-annotation-on-interface-or-class.html
Related
I need to instrument all methods, which implement an interface that itself is annotated. Consider such an example:
#WebService
interface HelloWorld {
void hello();
}
class HelloWorldImpl implements HelloWorld {
void hello() {...}
void goodBye() {...}
}
Here I need to have an advice around hello, because it is declared by an interface with #WebService annotation. Is it possible to build such a ButeBuddy matcher?
Yes, in the ElementMatchers class, you find a long row of predefined matchers, also such that deal with annotations. Do however know that annotations on interfaces are not inherited. You'd need to wrap the matcher in a ElementMatchers.hasSuperType to check the entire hierarchy.
I have recently reviewed a few spring projects.
I saw some interface which created for one class in dao and service layer of some projects.
like this:
public interface EmployeeDao(){
//some methods declaration
}
public class EmployeeDaoImp implements EmployeeDao (){
// methods overriding
}
public interface CompanyDao(){
//some methods declaration
}
public class CompanyDaoImp implements CompanyDao (){
// methods overriding
}
there is no need to Polymorphism in this case.
why we need to these interfaces?,what is advantage of these?.
I hope I could express myself.
Spring uses interfaces a lot because they follow the design principle "Program to an interface not to an implementation"
See Programming to an interface
When I have an Interface, for example:
public interface Model {
String toString();
}
And I want that every class that implements this Interface will use the following Annotations:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
So it will look like this in the Interface:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public interface Model {
String toString();
}
And a test class:
#XmlRootElement(name = "user")
public class User implements Model {
}
Something like this example doesn't work. How can I perform that, an abstract class with the annotations is maybe the solution?
Thank you in advance!
A class never inherits annotations from the interfaces it implements. Annotations that are so designated can be inherited from superclasses, but that's a characteristic of the annotation, and not the default. If the annotations you are trying to use happen to be inheritable in that way -- you'll have to check their documentation -- then you can cause them to be inherited by deriving all your model classes from a common, annotated, superclass.
Really, though, what's so bad about annotating each class explicitly? It's clearer, and no more verbose than implementing an interface.
I'm creating some resource class with same form so a good idea is use DRY and use inheritance.
So I've create a RootResource class and put some methods there. I want to annotate them and then implement them in subclass but it doesn't work! Here is a sample code:
public abstract class RootResource {
#GET
#Path("/{id: .*}")
public abstract String getInfo(String uid);
}
#Path("/user")
public class UserResource extends RootResource{
public String getInfo(#PathParam("id") String uid) {
System.out.println("Hello!");
}
}
I'm using jersey 2.6.
Any Idea?
Thanks.
I've been through the same issue while using Jersey. The Java EE standard for JAX-RS states the following:
3.6 Annotation Inheritance
JAX-RS annotations MAY be used on the methods and method parameters of a > super-class or an implemented
interface. Such annotations are inherited by a corresponding sub-class
or implementation class method provided that method and its parameters
do not have any JAX-RS annotations of its own. Annotations on a
super-class take precedence over those on an implemented interface.
The precedence over conflicting annotations defined in multiple
implemented interfaces is implementation specific.
If a subclass or implementation method has any JAX-RS annotations then all of the annotations on the super class or interface method are
ignored.
While Jersey as the reference implementation is very strict with this statement, Resteasy implementation is more lenient and did the trick for me.
It's important to specify the path over the class since it's the root resource class so the it will get where to look at the class loading and not for individual overridden methods:
#Path("/account/member/")
public class RootResource {
. . .
I have an interface like this:
public interface IFoo{
#AnnotationTest(param="test")
String invoke();
}
and I implement this like this:
public class Foo implements IFoo{
#Override
public String invoke(){
Method method = new Object() {
}.getClass().getEnclosingMethod();
AnnotationTest ann = method.getAnnotation(AnnotationTest.class);
if(ann == null){
System.out.printl("Parent method's annotation is unreachable...")
}
}
}
If it is possible to reach parent's annotation, I want to learn the way of it.
Any help or idea will be appreciated.
You can use Spring AnnotationUtils.findAnnotation to read annotations from interfaces.
Example :
Interface I.java
public interface I {
#SomeAnnotation
void theMethod();
}
Implementing class A.java
public class A implements I {
public void theMethod() {
Method method = new Object() {}.getClass().getEnclosingMethod();
SomeAnnotation ann = AnnotationUtils.findAnnotation(method, AnnotationTest.class);
}
}
It obviously requires to include in your project (and import) Spring framework classes.
There is no direct way to get it. If you really need, you have to manually loop over getInterfaces() to find if any implemented interface has the annotation. If you want to search for (eventually abstract) superclasses and the annotation is not #Inherited, you can again iterate the superclass chain until finding Object (*).
But beware, as following post states, there are good reasons for this not to be directly implemented in Java : Why java classes do not inherit annotations from implemented interfaces?
(*) If the annotation is #Inherited it is automatically searched on superclasses, but not on interfaces.
you can't inherit annotations.
But a framework that uses an annotation can check to see if annotation is present on superclass