Fast, lightweight, Spring like, annotation driven dependency injection framework.
Designed specifically for small applications, that has to have small memory footprint, small jar size and fast startup time, for example plugins, (embedded) standalone application, integration tests, jobs, Android applications, etc.
-
Similar to Spring annotation-support.
-
Classpath scanning for beans
-
Android support
-
Stereotype annotations to create a bean
@Component
,@Service
-
Component scan at compile time
-
@Configuration
can be applied to classes, annotated class can contain multiple@Bean
annotated methods, these methods will be automatically called, and their return value will be injected to the context -
@Autowired
can be applied to constructor, fields, setters to automatically set dependency (or even collection of dependencies) -
@Value
can be applied to constructors, fields, setters to get value from property file -
@PropertySource
annotation can be set to components to load property files -
@PostConstruct/@PreDestroy
annotations can be applied to methods to run post construct and pre destroy respectively -
@Scope("prototype") / @Scope("singleton")
can be applied to beans, prototype scope bean will be recreated for each getBean, singleton beans will be shared in the application context -
@Lazy
,@Eager
can be used to make beans initializing lazily or eagerly. (Lazy bean means slightly different thing than in Spring, see below limitation) -
By default all beans are lazily initialized
-
@Primary
can be used to declare a bean as primary in case of bean collision (useful for mocking out dependencies) -
@ComponentScan
and@Import
support to load more beans in other packages -
Conditional bean support, based on existence of other beans, classes, properties
-
JUnit test support (
@Autowire
to test, and automatically create Mockito mocks (@MockBean
,@SpyBean
) and inject into the test to test) -
Fast startup time, small memory footprint (see performance section (soon))
See samples in:
Include the jar file in your project. You can do this using Maven:
<dependency>
<groupId>com.helospark</groupId>
<artifactId>lightdi</artifactId>
<version>${lightdi.version}</version>
</dependency>
(Check mvnrespotiroy.com for the latest version).
You can also download the single-jar version from Maven central for direct usage:
(jar-with-dependencies is a Maven classifier, if you would like to use the fat jar using Maven)
Annotate beans with above annotations
LightDiContext context = lightDi.initContextByPackage(ConstructorDependency.class.getPackage().getName());
SomeClass someClass = context.getBean(SomeClass.class);
someClass.doSomething();
SomeClass (and all of it’s dependencies) has to be annotated with @Component.
If you started a project with LightDI, but realize, that you will need more features that LightDI won’t provide, you should be able to move to Spring relatively simply. It could be done by replacing annotation package names, and change the class that creates the context.
If you started a project in Spring, and only used DI features, moving to LightDI should also be fairly straightforward, following the above steps in reverse. Therefore you could get a more lightweight application.
LightDI is usable for Android, but please note the following:
The library is built using Java 8, so you need to add the following option to your Gradle file:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Since Android does not support runtime classpath scanning (see DexFile class), therefore compile time annotation processing is added. While this is a standard Java feature, IDEs may not turn it on by default to get support in Android Studio you need to enable it at:
Settings > Build, Execution, Deployment > Compiler > Annotation Processors > Enable annotation processing
and add the LightDi jar as a annotationProcessor explicitly in your build.gradle
file, like:
dependencies {
...
implementation 'com.helospark:lightdi:{version you would like to use}'
annotationProcessor 'com.helospark:lightdi:{version you would like to use}'
...
}
Statistics coming soon
LightDI was designed to be much more lightweight than Spring, it also has many of Spring’s feature lacking.
-
Only Java 8 supported at the moment, later it might be downgraded
-
LightDi does not use AOP, therefore if you manually call
@Component
class' methods, it will create new instances (even for singletons), therefore, you should not manually invoke these methods. If you need these beans, you can always inject it (and then it will be singleton) -
In LightDI by default every Bean is lazy unless otherwise specified. Lazy means different things in Spring and LightDI. Spring will inject a proxy of a Lazy bean to other beans, and instantiates it when there is a call on the proxy, in LightDI it just means, until requested, it will not be instantiated (requested by getBean, or a dependency of an initialized bean)
-
More will come soon
-
0.0.6 — When
@Value’s property `required=false
and they key not available it will no longer fills String with empty String. For fields value is unchanged, for methodnull
is passed. -
0.0.8 — When injecting a Collection of beans, beans witch are also collections but contain matching bean types are flatmapped (merged) (see MergeBeanListIT for example)
-
0.0.9 — Beans created via
@Bean
will have autowired dependencies injected
This framework shamelessly copied the the usage and idea from Spring framework, even down to annotation names. So why I have not just used Spring instead?
While Spring is great, but even with absolute minimal number of dependencies has a large size (in jars), it also takes long to start it up (ex. lazy context creation and startup cannot be achieved on first usage, since it is very expensive to start the context), also has fairly large memory footprint that is not good for embedded applications.
For several of my smaller project I found, that just the (Spring) DI framework used up more space in my jars, than all other dependencies (including my code) together.
There are already large number of other DI frameworks out there, but I have not been able to find another DI framework, that has classpath scanning, annotations support combined with fast startup time, low memory footprint, therefore the idea of LightDI was born.