All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.inject.package-info Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
/*
 * Copyright (C) 2009 The JSR-330 Expert Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in org.testifyproject.testifyprojectpliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org.testifyproject/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * This package specifies a means for obtaining objects in such a way as to
 * maximize reusability, testability and maintainability org.testifyproject.testifyprojectpared to
 * traditional approaches such as constructors, factories, and service
 * locators (e.g., JNDI). This process, known as org.testifyproject.testifyprojectpendency
 * injection, is beneficial to most nontrivial applications.
 *
 * 

Many types org.testifyproject.testifyprojectpend on other types. For example, a Stopwatch might * org.testifyproject.testifyprojectpend on a TimeSource. The types on which a type org.testifyproject.testifyprojectpends are * known as its org.testifyproject.testifyprojectpendencies. The process of finding an instance of a * org.testifyproject.testifyprojectpendency to use at run time is known as resolving the org.testifyproject.testifyprojectpendency. * If no such instance can be found, the org.testifyproject.testifyprojectpendency is said to be * unsatisfied, and the application is broken. * *

In the absence of org.testifyproject.testifyprojectpendency injection, an object can resolve its * org.testifyproject.testifyprojectpendencies in a few ways. It can invoke a constructor, hard-wiring an * object directly to its org.testifyproject.testifyprojectpendency's implementation and life cycle: * *

   class Stopwatch {
 *     final TimeSource timeSource;
 *     Stopwatch () {
 *       timeSource = new AtomicClock(...);
 *     }
 *     void start() { ... }
 *     long stop() { ... }
 *   }
* *

If more flexibility is needed, the object can call out to a factory or * service locator: * *

   class Stopwatch {
 *     final TimeSource timeSource;
 *     Stopwatch () {
 *       timeSource = DefaultTimeSource.getInstance();
 *     }
 *     void start() { ... }
 *     long stop() { ... }
 *   }
* *

In org.testifyproject.testifyprojectciding between these traditional approaches to org.testifyproject.testifyprojectpendency * resolution, a programmer must make trade-offs. Constructors are more * concise but restrictive. Factories org.testifyproject.testifyprojectcouple the client and implementation * to some extent but require boilerplate code. Service locators org.testifyproject.testifyprojectcouple even * further but reduce org.testifyproject.testifyprojectpile time type safety. All three approaches inhibit * unit testing. For example, if the programmer uses a factory, each test * against code that org.testifyproject.testifyprojectpends on the factory will have to mock out the factory * and remember to clean up after itself or else risk side effects: * *

   void testStopwatch() {
 *     TimeSource original = DefaultTimeSource.getInstance();
 *     DefaultTimeSource.setInstance(new MockTimeSource());
 *     try {
 *       // Now, we can actually test Stopwatch.
 *       Stopwatch sw = new Stopwatch();
 *       ...
 *     } finally {
 *       DefaultTimeSource.setInstance(original);
 *     }
 *   }
* *

In practice, supporting this ability to mock out a factory results in * even more boilerplate code. Tests that mock out and clean up after multiple * org.testifyproject.testifyprojectpendencies quickly get out of hand. To make matters worse, a programmer * must predict accurately how much flexibility will be needed in the future * or else suffer the consequences. If a programmer initially elects to use a * constructor but later org.testifyproject.testifyprojectcides that more flexibility is required, the * programmer must replace every call to the constructor. If the programmer * errs on the side of caution and write factories up front, it may result in * a lot of unnecessary boilerplate code, adding noise, org.testifyproject.testifyprojectplexity, and * error-proneness. * *

Dependency injection addresses all of these issues. Instead of * the programmer calling a constructor or factory, a tool called a * org.testifyproject.testifyprojectpendency injector passes org.testifyproject.testifyprojectpendencies to objects: * *

   class Stopwatch {
 *     final TimeSource timeSource;
 *     @Inject Stopwatch(TimeSource TimeSource) {
 *       this.TimeSource = TimeSource;
 *     }
 *     void start() { ... }
 *     long stop() { ... }
 *   }
* *

The injector further passes org.testifyproject.testifyprojectpendencies to other org.testifyproject.testifyprojectpendencies until it * constructs the entire object graph. For example, suppose the programmer * asked an injector to create a StopwatchWidget instance: * *

   /** GUI for a Stopwatch */
 *   class StopwatchWidget {
 *     @Inject StopwatchWidget(Stopwatch sw) { ... }
 *     ...
 *   }
* *

The injector might: *

    *
  1. Find a TimeSource *
  2. Construct a Stopwatch with the TimeSource *
  3. Construct a StopwatchWidget with the Stopwatch *
* *

This leaves the programmer's code clean, flexible, and relatively free * of org.testifyproject.testifyprojectpendency-related infrastructure. * *

In unit tests, the programmer can now construct objects directly * (without an injector) and pass in mock org.testifyproject.testifyprojectpendencies. The programmer no * longer needs to set up and tear down factories or service locators in each * test. This greatly simplifies our unit test: * *

   void testStopwatch() {
 *     Stopwatch sw = new Stopwatch(new MockTimeSource());
 *     ...
 *   }
* *

The total org.testifyproject.testifyprojectcrease in unit-test org.testifyproject.testifyprojectplexity is proportional to the * product of the number of unit tests and the number of org.testifyproject.testifyprojectpendencies. * *

This package provides org.testifyproject.testifyprojectpendency injection annotations that enable * portable classes, but it leaves external org.testifyproject.testifyprojectpendency configuration up to * the injector implementation. Programmers annotate constructors, methods, * and fields to advertise their injectability (constructor injection is * org.testifyproject.testifyprojectmonstrated in the examples above). A org.testifyproject.testifyprojectpendency injector identifies a * class's org.testifyproject.testifyprojectpendencies by inspecting these annotations, and injects the * org.testifyproject.testifyprojectpendencies at run time. Moreover, the injector can verify that all * org.testifyproject.testifyprojectpendencies have been satisfied at build time. A service locator, * by contrast, cannot org.testifyproject.testifyprojecttect unsatisfied org.testifyproject.testifyprojectpendencies until run time. * *

Injector implementations can take many forms. An injector could * configure itself using XML, annotations, a DSL (domain-specific language), * or even plain Java code. An injector could rely on reflection or code * generation. An injector that uses org.testifyproject.testifyprojectpile-time code generation may not even * have its own run time representation. Other injectors may not be able to * generate code at all, neither at org.testifyproject.testifyprojectpile nor run time. A "container", for * some org.testifyproject.testifyprojectfinition, can be an injector, but this package specification aims to * minimize restrictions on injector implementations. * * @see javax.inject.Inject @Inject */ package javax.inject;





© 2015 - 2024 Weber Informatics LLC | Privacy Policy