Simple Java singleton dependency injection via Reflections.
Almost everyone, who is used to dependency injections, likes the idea of injecting of services via an annotation in a class. For some microprojects or microservices could be Deltaspike, Spring, etc. incredible large with many function, that will not be used.
Wireable allows to create very simple application context, that scans defined package (and its subpackages). All classes with annotation @Wireable
are added into the mentioned application context as an instance. These classes will have injected all members with annotation @Wired
with reflections and then all methods (without arguments) with annotations @OnCreate
and @OnStartup
are executed.
Since 0.3.0
interfaces are supported as @Wired classes. If multiple classes points to similar interface, it it better to specify in your @Wireable
annotation the priorityFor
value by interface class.
Wireable is dependency-free with minimal size in units of kilobytes.
<dependency>
<groupId>cz.tvrzna</groupId>
<artifactId>wireable</artifactId>
<version>0.3.4</version>
</dependency>
Try to image a simple HTTP server, that serves data from database.
Main.java
package test.project;
import cz.tvrzna.wireable.WireableContext;
import cz.tvrzna.wireable.exceptions.WireableException;
public class Main
{
public static void main(String[] args)
{
try
{
WireableContext.init("test.project");
}
catch (WireableException e)
{
e.printStackTrace();
}
}
}
DatabaseService.java
package test.project;
import cz.tvrzna.wireable.annotations.OnCreate;
import cz.tvrzna.wireable.annotations.Wireable;
import cz.tvrzna.wireable.enums.PriorityLevel;
@Wireable
public class DatabaseService
{
private String[] data;
@OnCreate
private void init()
{
data = new String[] { "First", "Second", "Third" };
}
@OnCreate(priority = PriorityLevel.LOW)
private void reinit()
{
data = new String[] { "First", "Second", "Third", "Fourth"};
}
public String[] getData()
{
return data;
}
public void removeUserSession(Long id)
{
// Remove token
}
}
WebserverService.java
package test.project;
import cz.tvrzna.wireable.WireableContext;
import cz.tvrzna.wireable.annotations.OnEvent;
import cz.tvrzna.wireable.annotations.OnStartup;
import cz.tvrzna.wireable.annotations.Wireable;
import cz.tvrzna.wireable.annotations.Wired;
import cz.tvrzna.wireable.exceptions.WireableException;
@Wireable
public class WebserverService
{
@Wired
private DatabaseService databaseService;
@OnStartup
private void start()
{
// Create endpoint, that points on URL and method handleRequest
// Start server
}
public Response handleRequest(HttpRequest request) throws WireableException
{
WireableContext.fireEvent("doLogout", 1200l);
return Response.ok(databaseService.getData()).build();
}
}
WatcherService.java
package test.project;
import cz.tvrzna.wireable.WireableContext;
import cz.tvrzna.wireable.annotations.OnEvent;
import cz.tvrzna.wireable.annotations.OnStartup;
import cz.tvrzna.wireable.annotations.Unwireable;
import cz.tvrzna.wireable.exceptions.WireableException;
@Unwireable
public class WatcherService
{
@OnStartup
private void onStartup()
{
// Watch some data changes
}
@OnEvent("doLogout")
public void logout(Long id) throws WireableException
{
LateClass watcher = new LateClass();
WireableContext.wireObjects(watcher);
watcher.handleId(id);
}
}
LateClass.java
package test.project;
import cz.tvrzna.wireable.annotations.Wired;
public class LateClass
{
@Wired
private DatabaseService databaseService;
public void handleId(Long id)
{
databaseService.removeUserSession(id);
}
}
WireableContext.init("test.project");
starts initialization of the WireableContext on the start of Main class and scans packagetest.project
, which contains these classes.DatabaseService
andWebserverService
are initialized as instance, since they have@Wireable
or@Unwireable
annotation, and are put intoHashMap
in WireableContext. These classes needs to have the constructor without arguments.DatabaseService
andWebserverService
are listed for@Wired
annotation members.WebserverService
has one, so it adds reference ofDatabaseService
from WireableContext on member nameddatabaseService
.@Unwireable
clases could not by@Wired
.- Both service classes are scanned for methods without arguments with annotation
@OnCreate
, it is aware of OnCreate priority level.DatabaseService
has private method init(), so this method is invoked and variabledata
is set. - As it was in step before, classes are scanned again, but for methods without arguments with
@OnStartup
annotation.WebserverService
has private method start(), so this method is invoked and server is started. - If handleRequest method is called, it calls event
doLogout
. That invokes method annotated as@OnEvent("doLogout")
with all passed arguments. - When logout method of
WatcherService
is called, it creates new instance ofLateClass
. This method is out of context, but all@Wired
annotated members, becames accessable. This kind of classes could have any constructor, but@OnCreate
,@OrStartup
nor@OnEvent
methods are not invoked.