{"id":13485739,"url":"https://github.com/zsoltherpai/feather","last_synced_at":"2026-01-11T17:46:52.248Z","repository":{"id":41501012,"uuid":"42950091","full_name":"zsoltherpai/feather","owner":"zsoltherpai","description":"Lightweight dependency injection for Java and Android (JSR-330)","archived":false,"fork":false,"pushed_at":"2018-04-18T07:20:19.000Z","size":253,"stargazers_count":354,"open_issues_count":15,"forks_count":57,"subscribers_count":21,"default_branch":"master","last_synced_at":"2024-10-30T20:45:44.384Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zsoltherpai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-22T17:39:29.000Z","updated_at":"2024-10-22T11:05:26.000Z","dependencies_parsed_at":"2022-08-24T17:51:28.945Z","dependency_job_id":null,"html_url":"https://github.com/zsoltherpai/feather","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zsoltherpai%2Ffeather","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zsoltherpai%2Ffeather/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zsoltherpai%2Ffeather/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zsoltherpai%2Ffeather/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zsoltherpai","download_url":"https://codeload.github.com/zsoltherpai/feather/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245910887,"owners_count":20692513,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T18:00:30.903Z","updated_at":"2026-01-11T17:46:52.221Z","avatar_url":"https://github.com/zsoltherpai.png","language":"Java","readme":"#### About Feather\n[Feather](http://zsoltherpai.github.io/feather) is an ultra-lightweight dependency injection ([JSR-330](https://jcp.org/en/jsr/detail?id=330 \"JSR-330\"))\nlibrary for Java and Android. Dependency injection frameworks are often perceived as \"magical\" and complex. \nFeather - with just a few hundred lines of code - is probably the easiest, tiniest, most obvious one, \nand is quite efficient too (see comparison section below).\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.codejargon.feather\u003c/groupId\u003e\n    \u003cartifactId\u003efeather\u003c/artifactId\u003e\n    \u003cversion\u003e1.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n[Javadoc](http://zsoltherpai.github.io/feather/apidocs \"Javadoc\") for Feather\n##### Usage - code examples\n###### Create Feather (the injector)\n```java\nFeather feather = Feather.with();\n```\nAn application typically needs a single Feather instance.\n\n###### Instantiating dependencies\nDependencies with @Inject constructor or a default constructor can be injected by Feather without the need for\nany configuration. Eg:\n```java\npublic class A {\n    @Inject\n    public A(B b) {\n        // ...\n    }\n}\n\npublic class B {\n    @Inject\n    public B(C c, D d) {\n        // ...\n    }\n}\n\npublic class C {}\n\n@Singleton\npublic class D {\n    // something expensive or other reasons for being singleton\n}\n```\nCreating an instance of A:\n```java\nA a = feather.instance(A.class);\n```\n###### Providing additional dependencies to Feather\nWhen injecting an interface, a 3rd party class or an object needing custom instantiation, Feather relies on configuration\nmodules providing those dependencies:\n```java\npublic class MyModule {\n    @Provides\n    @Singleton // an app will probably need a single instance \n    DataSource ds() {\n        DataSource dataSource = // instantiate some DataSource\n        return dataSource;\n    }\n}\n```\nSetting up Feather with module(s):\n```java\nFeather feather = Feather.with(new MyModule());\n```\nThe DataSource dependency will now be available for injection:\n```java\npublic class MyApp {\n    @Inject \n    public MyApp(DataSource ds) {\n        // ...\n    }\n}\n```\nFeather injects dependencies to @Provides methods aguments. This is particularly useful for binding an implementation\nto an interface:\n```java\npublic interface Foo {}\n\npublic class FooBar implements Foo {\n    @Inject\n    public FooBar(X x, Y y, Z z) {\n        // ...\n    }\n}\n\npublic class MyModule {\n    @Provides\n    Foo foo(FooBar fooBar) {\n        return fooBar;\n    }\n}\n\n// injecting an instance of Foo interface will work using the MyModule above:\npublic class A {\n    @Inject\n    public A(Foo foo) {\n        // ...\n    }\n}\n```\nNote that the @Provides method serves just as a binding declaration here, no manual instantiation needed\n###### Qualifiers\nFeather supports Qualifiers (@Named or custom qualifiers)\n```java\npublic class MyModule {\n    @Provides\n    @Named(\"greeting\")\n    String greeting() {\n        return \"hi\";\n    }\n        \n    @Provides\n    @SomeQualifier\n    Foo some(FooSome fooSome) {\n        return fooSome;\n    };\n}\n```\nInjecting:\n```java\npublic class A {\n    @Inject\n    public A(@SomeQualifier Foo foo, @Named(\"greeting\") String greet) {\n        // ...\n    }\n}\n```\nOr directly from feather:\n```java\nString greet = feather.instance(String.class, \"greeting\");\nFoo foo = feather.instance(Key.of(Foo.class, SomeQualifier.class));\n```\n###### Provider injection\nFeather injects [Provider](https://docs.oracle.com/javaee/6/api/javax/inject/Provider.html)s  to facilitate lazy loading or circular dependencies:\n```java\npublic class A {\n    @Inject\n    public A(Provider\u003cB\u003e b) {\n        B b = b.get(); // fetch a new instance when needed\n    }\n}\n```\nOr getting a Provider directly from Feather:\n```java\nProvider\u003cB\u003e bProvider = feather.provider(B.class);\n```\n###### Override modules\n```java\npublic class Module {\n    @Provides\n    DataSource dataSource() {\n        // return a mysql datasource\n    }\n    \n    // other @Provides methods\n}\n\npublic class TestModule extends Module {\n    @Override\n    @Provides\n    DataSource dataSource() {\n        // return a h2 datasource\n    }\n}\n```\n###### Field injection\nFeather supports Constructor injection only when injecting to a dependency graph. It inject fields also if it's\nexplicitly triggered for a target object - eg to facilitate testing. A simple example with a junit test:\n```java\npublic class AUnitTest {\n    @Inject\n    private Foo foo;\n    @Inject\n    private Bar bar;\n\n    @Before\n    public void setUp() {\n        Feather feather = // obtain a Feather instance\n        feather.injectFields(this);\n    }\n}\n```\n###### Method injection\nNot supported. The need for it can be generally avoided by a Provider / solid design (favoring immutability, injection via constructor).\n\n##### Android example\n```java\nclass ExampleApplication extends Application {\n    private Feather feather;\n\n    @Override public void onCreate() {\n        // ...\n        feather = Feather.with( /* modules if needed*/ );\n    }\n\n    public Feather feather() {\n        return feather;\n    }\n}\n\nclass ExampleActivity extends Activity {\n    @Inject\n    private Foo foo;\n    @Inject\n    private Bar bar;\n\n  @Override public void onCreate(Bundle savedState) {\n    // ...\n    ((ExampleApplication) getApplication())\n        .feather()\n            .injectFields(this);\n  }\n}\n```\nFor best possible performance, dependencies should be immutable and @Singleton. See full example in android-test.\n##### Footprint, performance, comparison\nSmall footprint and high performance is in Feather's main focus.\n- compared to [Guice] (https://github.com/google/guice \"Guice\"): 1/50 the library size, ~10x startup speed\n- compared to [Dagger](http://square.github.io/dagger): 1/4 the library size (of just Dagger's run-time part), ~2x startup speed\n\nNote: startup means creation of the container and instantiation of an object graph. Executable comparison including Spring, \nGuice, Dagger, PicoContainer is in 'performance-test' module.\n\n##### How it works under the hood\nFeather is based on optimal use of reflection to provide dependencies. No code generating, classpath scanning, proxying or anything\ncostly involved.\n\nA simple example with some explanation:\n```java\nclass A {\n    @Inject\n    A(B b) {\n\n    }\n}\n\nclass B {\n\n}\n```\nWithout the use of Feather, class A could be instantiated with the following factory methods:\n```java\nA a() {\n    return new A(b());\n}\n\nB b() {\n    return new B();\n}\n```\nMost of the information in these factories are redundant and they tend to be hot spots for changes and\nsources for merge hells. Feather avoids the need for writing such factories - by doing the same thing\ninternally: When an instance of A is injected, Feather calls A's constructor with the necessary arguments - an\ninstance of B. That instance of B is created the same way \\- a simple recursion, this time with no further dependencies \\- and the instance of A is created.\n\n","funding_links":[],"categories":["项目","Projects","Java","IoC"],"sub_categories":["依赖注入","Dependency Injection"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzsoltherpai%2Ffeather","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzsoltherpai%2Ffeather","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzsoltherpai%2Ffeather/lists"}