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.DatabaseServiceandWebserverServiceare initialized as instance, since they have@Wireableor@Unwireableannotation, and are put intoHashMapin WireableContext. These classes needs to have the constructor without arguments.DatabaseServiceandWebserverServiceare listed for@Wiredannotation members.WebserverServicehas one, so it adds reference ofDatabaseServicefrom WireableContext on member nameddatabaseService.@Unwireableclases could not by@Wired.- Both service classes are scanned for methods without arguments with annotation
@OnCreate, it is aware of OnCreate priority level.DatabaseServicehas private method init(), so this method is invoked and variabledatais set. - As it was in step before, classes are scanned again, but for methods without arguments with
@OnStartupannotation.WebserverServicehas 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
WatcherServiceis called, it creates new instance ofLateClass. This method is out of context, but all@Wiredannotated members, becames accessable. This kind of classes could have any constructor, but@OnCreate,@OrStartupnor@OnEventmethods are not invoked.