Skip to content

helospark/light-di

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

87 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status Coverage MIT licence PRs Welcome

LightDI

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.

Features

  • 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))

Usage

Include library

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)

Library usage

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.

Notes for Android

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}'
       ...
    }

Performance

Statistics coming soon

Limitation

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

Incompatibilities between versions

  • 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 method null 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

Why another DI framework

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.

Building and contribution

You can build using Maven:

     mvn clean install -DskipGpgSign

Feel free to open issues / pull requests.

About

Fast, lightweight, Spring like, annotation driven dependency injection framework.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages