I'm working on something that might benefit from a pattern like the following:
public abstract class SomeBuisnessThingy()
{
protected int someDatapoint;
}
public class ADatabaseThingy() extends SomeBusinessThingy()
{
#SomeJPAAnnotation
???? someDatapoint;
}
public class AWebServiceThingy() extends SomeBusinessThingy()
{
#SomeSOAPStuff
???? someDatapoint;
}
It smells more like an interface than an abstract class, but the same thing needs to be done. I have a DB implementation of that class and a WS implementation of that class.
Those representations are very similar, but may be different. For example the WS class may expose a field as a String so a 3rd party can easily do an integration, it can also be splot into its own package so we can hand a customer some lightweight WebService or POJO classes without all the baggage of the DB or a JPA framework coming with it. Perhaps it could be used to create the basic classes needed for something then switch between persistence frameworks that use different annotations.
Is it possible to ADD annotations to inherited fields?
No. If you need to annotate inherited members, you need to annotate the methods, not the fields.
Related
Can I do it with reflection or something like that?
I have been searching for a while and there seems to be different approaches, here is a summary:
reflections library is pretty popular if u don't mind adding the dependency. It would look like this:
Reflections reflections = new Reflections("firstdeveloper.examples.reflections");
Set<Class<? extends Pet>> classes = reflections.getSubTypesOf(Pet.class);
ServiceLoader (as per erickson answer) and it would look like this:
ServiceLoader<Pet> loader = ServiceLoader.load(Pet.class);
for (Pet implClass : loader) {
System.out.println(implClass.getClass().getSimpleName()); // prints Dog, Cat
}
Note that for this to work you need to define Petas a ServiceProviderInterface (SPI) and declare its implementations. you do that by creating a file in resources/META-INF/services with the name examples.reflections.Pet and declare all implementations of Pet in it
examples.reflections.Dog
examples.reflections.Cat
package-level annotation. here is an example:
Package[] packages = Package.getPackages();
for (Package p : packages) {
MyPackageAnnotation annotation = p.getAnnotation(MyPackageAnnotation.class);
if (annotation != null) {
Class<?>[] implementations = annotation.implementationsOfPet();
for (Class<?> impl : implementations) {
System.out.println(impl.getSimpleName());
}
}
}
and the annotation definition:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.PACKAGE)
public #interface MyPackageAnnotation {
Class<?>[] implementationsOfPet() default {};
}
and you must declare the package-level annotation in a file named package-info.java inside that package. here are sample contents:
#MyPackageAnnotation(implementationsOfPet = {Dog.class, Cat.class})
package examples.reflections;
Note that only packages that are known to the ClassLoader at that time will be loaded by a call to Package.getPackages().
In addition, there are other approaches based on URLClassLoader that will always be limited to classes that have been already loaded, Unless you do a directory-based search.
What erickson said, but if you still want to do it then take a look at Reflections. From their page:
Using Reflections you can query your metadata for:
get all subtypes of some type
get all types annotated with some annotation
get all types annotated with some annotation, including annotation parameters matching
get all methods annotated with some
In general, it's expensive to do this. To use reflection, the class has to be loaded. If you want to load every class available on the classpath, that will take time and memory, and isn't recommended.
If you want to avoid this, you'd need to implement your own class file parser that operated more efficiently, instead of reflection. A byte code engineering library may help with this approach.
The Service Provider mechanism is the conventional means to enumerate implementations of a pluggable service, and has become more established with the introduction of Project Jigsaw (modules) in Java 9. Use the ServiceLoader in Java 6, or implement your own in earlier versions. I provided an example in another answer.
Spring has a pretty simple way to acheive this:
public interface ITask {
void doStuff();
}
#Component
public class MyTask implements ITask {
public void doStuff(){}
}
Then you can autowire a list of type ITask and Spring will populate it with all implementations:
#Service
public class TaskService {
#Autowired
private List<ITask> tasks;
}
The most robust mechanism for listing all classes that implement a given interface is currently ClassGraph, because it handles the widest possible array of classpath specification mechanisms, including the new JPMS module system. (I am the author.)
try (ScanResult scanResult = new ClassGraph().whitelistPackages("x.y.z")
.enableClassInfo().scan()) {
for (ClassInfo ci : scanResult.getClassesImplementing("x.y.z.SomeInterface")) {
foundImplementingClass(ci); // Do something with the ClassInfo object
}
}
With ClassGraph it's pretty simple:
Groovy code to find implementations of my.package.MyInterface:
#Grab('io.github.classgraph:classgraph:4.6.18')
import io.github.classgraph.*
new ClassGraph().enableClassInfo().scan().withCloseable { scanResult ->
scanResult.getClassesImplementing('my.package.MyInterface').findAll{!it.abstract}*.name
}
What erikson said is best. Here's a related question and answer thread - http://www.velocityreviews.com/forums/t137693-find-all-implementing-classes-in-classpath.html
The Apache BCEL library allows you to read classes without loading them. I believe it will be faster because you should be able to skip the verification step. The other problem with loading all classes using the classloader is that you will suffer a huge memory impact as well as inadvertently run any static code blocks which you probably do not want to do.
The Apache BCEL library link - http://jakarta.apache.org/bcel/
Yes, the first step is to identify "all" the classes that you cared about. If you already have this information, you can enumerate through each of them and use instanceof to validate the relationship. A related article is here: https://web.archive.org/web/20100226233915/www.javaworld.com/javaworld/javatips/jw-javatip113.html
Also, if you are writing an IDE plugin (where what you are trying to do is relatively common), then the IDE typically offers you more efficient ways to access the class hierarchy of the current state of the user code.
I ran into the same issue. My solution was to use reflection to examine all of the methods in an ObjectFactory class, eliminating those that were not createXXX() methods returning an instance of one of my bound POJOs. Each class so discovered is added to a Class[] array, which was then passed to the JAXBContext instantiation call. This performs well, needing only to load the ObjectFactory class, which was about to be needed anyway. I only need to maintain the ObjectFactory class, a task either performed by hand (in my case, because I started with POJOs and used schemagen), or can be generated as needed by xjc. Either way, it is performant, simple, and effective.
A new version of #kaybee99's answer, but now returning what the user asks: the implementations...
Spring has a pretty simple way to acheive this:
public interface ITask {
void doStuff();
default ITask getImplementation() {
return this;
}
}
#Component
public class MyTask implements ITask {
public void doStuff(){}
}
Then you can autowire a list of type ITask and Spring will populate it with all implementations:
#Service
public class TaskService {
#Autowired(required = false)
private List<ITask> tasks;
if ( tasks != null)
for (ITask<?> taskImpl: tasks) {
taskImpl.doStuff();
}
}
I have modifiers such as protected, private and private transient. I am using manual wiring.
I need to use setter injection. Which all variables do I need to wire?
This depends on YOUR needs, not on the needs of Spring.
Because you have setters, then I recommend to make the variables private.
transient would only be taken in account when you serialize this class (the call it must implement the Serializabe interface), but this is highly unusual, so I would not add transisient as long as the class is not Serializabe
Dependency Injection is a software design pattern that implements inversion of control for resolving dependencies. Dependency injection means giving an object its instance variables.
It's like making the class independent of the implementation details of other services (e.g.) that it uses.
e.g.
public class MyClass{
private OtherService os = new OtherServiceImpl();
...
}
In the above code, MyClass is dependent upon OtherServiceImpl. Let's say, in future we realize that OtherServiceImpl does not suffice all of our requirements, or there is another service MuchBetterServiceImpl which is provided by different vendor which helps us.
Now, if we modify MyClass to use MuchBetterServiceImpl as
private OtherService os = new MuchBetterServiceImpl();
We would need to re-comiple and re-test MyClass again.
But with coming in of Autowiring and mocking tools we can make MyClass independent of implementation details of OtherService.
public class MyClass{
#Autowired
private OtherService os ;
...
}
For your particular case, this can be achieved as
public class MyClass{
private OtherService os ;
public OtherService getOs(){
return os;
}
#Autowired
public void setOd(OtherService pOs){
os=pOs;
}
...
}
Whatever way is it done Setter/Constructor it is providing de-coupling the two classes.
Now, to spring it does not matter if you are autowiring what type of fields. As the responsibility of spring is to find a suitable implementation and plug it in your class.
Spring uses reflection to do this linking. And setters should be public/accessible.
It doesn't matter what is the access modifier of your field.
refer this and this questions. for more details.
Coming to your question: What variables do you need to wire: Preferably all the services, controllers, Daos or any other components that you need to decouple should be auto wired.
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 class Validator, which manage all validation criteria from files and database. But this criteria are loaded by Loader like this:
Validator validator = Loader.load("clients"); //get all from clients.cfg file
What is the best approach to determine from another class, which criteria are currently loaded?
Importer importer;
Validator clientsValidator = Loader.load("clients");
Validator addressValidator = Loader.load("address"); ...
importer.validate(data, clientsValidator, addressValidator);
public class Importer{
public void validate(Data data, Validator... validator){
...
validateClient(data, one of validators);
validateAddress(data, another of validator);
...
}
}
I need to know in Importer class, which Validator is for Clients, which for Addresses... Any good approaches?
The best way would be for you to be add a field and accompanying method to Validator to return the identifier (e.g. "clients") with which it was created.
Alternatively, if by using a different identifier when calling Loader.load() you get back instances of different classes implementing the Validator interface, then you can use the Object.getClass() method to tell those classes apart. If those classes are within a pretty small set you might even get away with using instanceof directly.
We would need more information, such as what Loader does exactly, what Validator is and how much you are allowed to change their code before being able to provide a more concrete answer.
EDIT:
Quite honestly, perhaps you should reconsider a redesign of your data model. As it stands, you can apparently mix clients and addresses without any checks. You should restructure your code to be able to rely on the type safety features of Java.
One way would be to have a generic class/interface Validator<T>, where T would the class of the validated objects:
public interface Validator<T> {
public boolean validate(T object);
}
You could then have specific Data subclasses for your data, such as Address or Client, and set typed Validator objects to Importer through specific methods:
public class Importer {
public void addAddressValidator(Validator<Address> validator) {
...
}
public void addClientValidator(Validator<Client> validator) {
...
}
}
This is far safer than mixing all validator objects in a single variadic method call, and it is also the preferred approach of most common frameworks in the wild.
Why not have a getSource() in Validator which gets set when Loader loads the source.
Thinking more about the specific question below :
I need to know in Importer class, which Validator is for Clients,
which for Addresses... Any good approaches?
Actually a better way to do this is if Loader can return a ClientValidator (implementation of Validator) for client and AddressValidator for addresses.
That way you can avoid the if-else conditions and directly call validate on the Validator class
Pass the validators by position. You must also check if the specific validator is null or not before you use.
public void validate(Data data,
Validator clientsValidator,
Validator addressValidator) {
...
if (clientsValidator != null) {
validateClient(data, clientsValidator);
}
if (addressValidator != null) {
validateAddress(data, addressValidator);
}
...
}
Persistent object:
#Entity
public class PersistentModelObject{
...
}
I need something like:
interface GenericDao<T annotated_with Entity>{
//crud
}
Or can it be simulated in some way (with extension, implementation, etc).
EDIT: Please someone who understands my question to edit it to some understandable level.
I dont think you can use annotations like that via generics, but you can use java.lang.Class java.lang.reflect.Field isAnnotationPresent(YourAnnotation.class) to check if a class is annotated with a certain annotation.
A better aproach might be using marker interfaces? Something like:
public class PersistentModelObject implements MyPersistableType{
...
}
and
interface MyPersistableType {} //marker interface
Then you may use it like this:
interface GenericDao<T extends MyPersistableType>{
//crud
}
But then again, it depends on what you are trying to solve.
This restriction can only be checked at runtime using reflection.