Reputation: 3680
I am developing Plain java code (no bean or container frameworks) and I wanted to achieve @PostConstruct
/ @PreDestroy
functionalities. Is that possible ?
I wrote a sample code to check the feasibility (code sample below). But the postContruct() and beforeDestroy() methods are not getting called.
How to achieve this ?
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class Test {
public static void main (String...strings) {
Test test = new Test();
System.out.println("Ready....");
test.sayHello();
System.out.println("Done...");
}
private void sayHello () {
System.out.println("Hello World !! ");
}
@PostConstruct
public void postConstruct() {
System.out.println("PostConstruct is called .. ");
}
@PreDestroy
public void beforeDestroy () {
System.out.println("beforeDestroy is called ");
}
}
The Output is
Ready....
Hello World !!
Done...
Upvotes: 2
Views: 6857
Reputation:
Well, the simplest way would be implement your own annotations and an utility class to manage instances, then you can execute methods for the post construct after instantiating the class and pre destroy before destroying the reference.
Calling a method last in a constructor would be practically the same, i dont imagine any case where its different.
Calling finalize is also a good option if you know what you are doing becaue it could not be called depending in the jvm and system configuration but that actually isnt a pre destructor it would be a destructor itself since you cant throw exceptions
You can implement AutoCloseable interface and instantiate the class in a try with resources and implement the close method thats going to be called
Upvotes: 0
Reputation: 23262
The comments that were mentioned on your question already state it: if you don't use a framework or tool that handles the annotations, then no, there is no way that those @PostConstruct
and @PreDestroy
-methods get called. As a side-note: you could also write your own AnnotationProcessor, but you will probably ending up writing a framework, where you could just use something like a CDI container of your choice (e.g. Weld, OpenWebBeans, etc.).
Now, how could you solve it without annotations? It depends what you want to achieve.
For example, if it doesn't really matter, that the @PostConstruct
isn't called exactly after the construction of the object, then an instance initalization block may serve your needs, e.g.
class Some {
{
// your initialization code... however! this is not the same as @PostConstruct
}
}
Regarding the @PreDestroy
you could overwrite Object.finalize
.
Be careful when you supply your own finalize
-implementation and read some articles regarding it, before you do.
Both solutions however are not 1:1 substitutes of the annotations, but they may be what you are looking for.
Here is an example class:
class PreDestroyPostConstruct {
PreDestroyPostConstruct() {
System.out.println("constructor");
}
{
System.out.println("initialization block");
}
@Override
protected void finalize() throws Throwable {
System.out.println("finalize");
}
}
Demonstrating the output:
PreDestroyPostConstruct obj = new PreDestroyPostConstruct();
obj = null;
System.out.println("Program finishing");
Possible output:
initialization block
constructor
finalize
Program finishing
Note, that there is no guarantee that finalize
is called before the "Program finishing"
-part and it may even happen that it isn't called/finished before the VM shuts down.
Upvotes: 3
Reputation: 120858
Theoretically you can have a static factory method that calls an init
method after it has constructed the Object.
private final init(){
.. your stuff after the constructor
}
public static MyObject of(int x){
MyObject obj = new MyObject(x);
init();
return obj;
}
You could do the same inside the constructor, but I don't like calling methods inside a constructor. In case you do, that method has to be final so that it does not get overridden.
Upvotes: 2