I have an api which has some base implementations. I have a factory which gives the instances of that api to the clients.
I want to change my factory to make it more generic so, if a new implementation of the api will be generated and its jar file will be put in classpath, the factory will understand it and any changes wouldn't be needed.
Use the java SPI, Service Provider Interface.
API jar - Provide one single interface.
Provider jar - Provide implementations in jars. You can even put several implementations in a jar. In a text file META-INF/services/my.package.MyInterface one lists implementing class(es).
Application - In the application the implementing jar should not be needed for compilation:
in maven scope runtime.
The service discovery happens with a ServiceLoader<T>:
public static void main(String[] args) {
ServiceLoader<MyInterface> loader = ServiceLoader.load(MyInterface.class);
for (MyInterface api : loader) {
api. ...
}
// Or take the first implementation:
MyInterface api = loader.iterator().next();
}
You could provide a class in the API jar with a static function for that discovery mechanism.
Advantages:
Separation
Several implementations possible
Selection of implementation can be done dynamically
Example of jars
xxx-api.jar
my/package/MyInterface.class
xxx-first-impl.jar
META-INF/services/my.package.MyInterface
my.package.impl.MyImpl1
my/package/impl/MyImpl1.class
public class MyImpl1 implements MyInterface { ... }
myapp1.jar
If you'd like to start with theory. Please read about Dependency inversion principle.
In object-oriented programming, the dependency inversion principle refers to a specific form of decoupling software modules. When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are inverted (i.e. reversed), thus rendering high-level modules independent of the low-level module implementation details.
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend on details. Details should depend on abstractions.
The principle inverts the way some people may think about object-oriented design, dictating that both high- and low-level objects must depend on the same abstraction.
Dependency Injection Library
As for specific implementations, you have many in Java. Specifically for the Dependency Injection approach. Spring Framework obviously comes to mind. But you can also look at Java EE Context and Dependency Injection.
Interface Injection
You can also...
Load the Jars manually : How should I load Jars dynamically at runtime?
Use Interface Injection : Spring interface injection example ( This title says Spring, but the answers show no Spring is needed for Interface Injection )
Related
In line with the Open-Closed Principle, I typically design my Java packages and libraries in such a way that there is a generic "interface" or "API" package/library and one or more implementations (quite similar to many common APIs like JDBC or JAXP/SAX).
To locate an implementation (or sometimes multiple implementations) in the base API library without violating OCP, I commonly use Java's ServiceLoader mechanism, or occasionally classpath scanning via third-party libraries like ClassGraph or Reflections. From a Maven perspective, the implementations are brought in as runtime dependencies (as they're only needed at execution time, but not at compile time). Pretty standard stuff.
So, now, I want to make some of these packages available as OSGi bundles (with API and implementation in separate bundles), but since in OSGi each bundle has its own class loader, neither classpath scanning nor the ServiceLoader API will work for this purpose. At first glance, OSGi's "fragment" mechanism seems to be the closest equivalent to the plain-Java setup described above. In that scenario, the API bundle would be the "fragment host", and concrete implementations would attach as fragments to that host bundle. As the fragment host and all its attached fragments use the same class loader, the standard plain-Java mechanisms like ServiceLoader or ClassGraph would conceivably still work. This would also have the advantage that there would be no need to detect whether a library/bundle is running in an OSGi context or not, and no OSGi framework dependencies are needed.
So, in a nutshell, my question is: are fragments the correct way to implement runtime-only dependencies in OSGi or is there a better (or more standard) way? Preferably, I'm looking for a solution that works in an OSGi container but does not require a dependency on OSGi itself.
No Fragments are almost always wrong outside the translations. The OSGi model is to use services.
The way to go then is to use DS. Using bnd (in maven, gradle, ant, sbt, or Bndtools) you can create components. A component is a Plain Old Java Object (POJO) that is annotated with injection and activation instructions. You could make those components to take all its dependencies in the constructor.
The bnd code uses the annotations to generate an XML file that is used in runtime to create, activate, inject, and register those components. This will then work out of the box in an OSGi Framework. The annotations are build time so they do not create dependencies in your runtime.
In your non-OSGi environment, you'd be responsible to call that constructor yourself. So you gather your dependencies using the Service Loader and then construct them in the right order.
#Component
public class MyComponent implements Foo {
final Bar bar;
#Activate
public MyComponent( #Reference Bar bar ) {
this.bar = bar;
}
...
}
My current project has multiple modules (NOT Java 9 modules) and I'm looking for a good way to do loose coupling between Spring-based application modules.
From my understanding, I could #Import configuration classes (from other application modules). But it has some limitations:
Dependency on implementation classes of other modules
No clear API to be exposed for the consumer modules
The disadvantages would limit the ability to replace a module by an equivalent module which implements same API.
I'm thinking about using interfaces for module APIs and the #Configuration classes would implement the API interfaces. And the #Import will be replaced by dependency on exposed API objects. I have prototype code here https://github.com/tha2015/springmodules/blob/master/src/main/java/dsl/Main.java
Is there a better way to do loose coupling between application modules?
Thanks.
In a past question I asked how to design a system where:
A class contains one or more optional methods.
Optional methods are implemented by plugins that may or not may be present at compile-time.
If a user invokes a method whose associated plugin is not present at compile-time, they will get a compile-time error.
I provided one possible solution that works in Java 8.
Unfortunately, this solution depends on the use of split packages (two modules exporting the same package) which are disallowed by the Java 9 Module System.
How can this be implemented in Java 9?
Services
If I have understood the question correctly what you're looking forward to using are Services from the module system.
Java has long supported services via the java.util.ServiceLoader
class, which locates service providers at run time by searching the
classpath.
The module system could identify uses of services by scanning the class files in module artifacts for invocations of the ServiceLoader::load method.
With your current project structure, you should define an abstract class or an interface that can be a extended of implemented in the guava, coremodule classes and is provided by them.
A module uses a particular service is an important aspect of that module’s definition, so for both efficiency and clarity its expressed in the module’s declaration with a uses clause:
module com.foo.bar.sql {
uses com.foo.Verifiers;
}
A module provides an implementation of a particular service is equally fundamental, however, this is put in the module’s declaration with a provides clause:
module guava {
provides com.foo.Verifiers with com.guava. GuavaVerifier;
}
module core {
provides com.foo.CoreVerifier with com.guava. GuavaVerifier;
}
I'm trying to integrate Single Responsibility Principle into my Java code by refactoring large classes (2000+ lines) into smaller, cohesive classes (~200 lines). However I'm confused how to properly reduce coupling between classes, since certain classes seem bound to be create multiple "hard dependencies" via the new keyword.
I'm using dependency injection via constructors primarily, followed by setter methods, or methods which accept the dependency as a parameter and use it amonst other logic within the method body (not just a simple this.val = val; setter.
IntelliJ's automatic refactoring instantiates this newly extracted class and passes (injects) it with a this reference to the LoadController. If I have to refactor a 2000 line class, of course this auto-instantiation + injection will occur each time I extract a new class out. The following LoadController is a JavaFX controller class for the program's main stage, which acts as the starting point for various features:
public class LoadController{
private final DBConnection dbConnection = new DBConnection(this);
private final UpdateLabels updateLabels = new UpdateLabels(this);
private final OpenCloseMenu openCloseMenu= new OpenCloseMenu (this);
private final CreateVBox createVBox= new CreateVBox (this, dbConnection);
private final ...
private final ...
}
Is this wrong? My understanding is that large, separate functions should be in their own class ... BUT some classes must have multiple hard dependencies like above, in order to "guide" the flow of logic between the use of various other classes.
If you are doing dependency injection into JavaFX controllers, you might want to look into using something like Gluon Ignite to assist you.
Gluon Ignite allows developers to use popular dependency injection frameworks in their JavaFX applications, including inside their FXML controllers. Gluon Ignite creates a common abstraction over several popular dependency injection frameworks
The injection framework you choose to use (e.g. Guice or Spring) will be responsible for creating the injectable components (e.g. you don't invoke new) and injecting the relevant references into your code, (e.g. you don't need to write dbConnection = <some value>). The injection framework will have extensive documentation and blog articles on how it works and how it may best be used, so full discussion of that is outside the scope of this answer.
An alternate to Gluon Ignite is afterburner.fx, which is similar but uses a small custom implementation for #Inject, so is more lightweight (and a little less powerful), then the more established dependency injection frameworks (very simple to use though).
This is just one option, there are other ways you can handle this, but seeing as you state that you wish to perform dependency injection with JavaFX, it seems to make sense of proven frameworks to do this rather than try to roll your own implementation.
some classes must have multiple hard dependencies like above, in order to "guide" the flow of logic between the use of various other classes.
Using something like Guice you provide a module that defines bindings between interface types and implementations. These bindings tell Guice how to construct the dependencies, so you don't need to hard code the dependencies in your classes. See the BillingModule in the Guice getting started guide for a module example. If you need multiple instances of injectable objects, you can use Providers in Guice. Spring has similar concepts, but different names.
Deciding on whether or not to use a dependency injection framework is a tradeoff between the work you would need to do if there was no injection framework vs the additional time and complexity of integrating the framework into your application. so the decision of whether or not to use one needs to be an architectural decision that you make, there is not a generic right or wrong answer for every application on whether use of such frameworks is justified.
I decide that using an injection framework is superfluous for my requirements, then I am not doing anything inherently incorrect by having multiple hard dependencies in some classes, as shown above?
Well the dependencies need to be defined somewhere. Either in an inferred or centralized location such as dependency injection systems use or local to given classes as you might determine from a traditional responsibility driven design approach. So you are not necessarily doing anything wrong by having hard dependencies. Abstract decoupling patterns such as dependency injection aren't always required.
The trick is determining what dependencies to have where and how to manage them. Often it is just obvious and falls out naturally from the problem domain, sometimes techniques such as CRC modeling can help structure dependencies.
Related article:
Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler.
My assumption is that I can refactor my large classes into smaller, cohesive classes with some of these classes having multiple hard dependencies, using new.
Yes, you can certainly do that.
Can an injection framework be integrated later on in a project's life, rather than early on when it may not be required yet?
Yes it can. It will be a bit of work to do so, but if the application is well structured, not all that difficult. It is more difficult to go the other way and try to remove usage of a dependency injection framework from applications and libraries that are already based on it.
Related:
Passing Parameters JavaFX FXML
I have learned Spring for quite some time (just learn, without actual hands-on experience on real project). In my understanding, Spring provides a DI frameworks, which allows centralize way of connecting / wiring all the classes in one place. The classes themselves do not compose / instantiate other components.
I can understand, DI allows easier unit-testing for each component as they are depending on interface.
My question is, why does wiring all the classes in centralize way (externally) helps in development process (besides testing), compared to traditional way (each class instantiates another class).
This link on DI explains it pretty well:
http://en.wikipedia.org/wiki/Dependency_injection#Motivation
The primary purpose of the dependency injection pattern is to allow selection among multiple implementations of a given dependency interface at runtime, or via configuration files, instead of at compile time. The pattern is particularly useful for providing "mock" test implementations of complex components when testing; but is often used for locating plugin components, or locating and initializing software services.
Unit testing of components in large software systems is difficult, because components under test often require the presence of a substantial amount of infrastructure and set up in order to operate at all. Dependency injection simplifies the process of bringing up a working instance of an isolated component for testing. Because components declare their dependencies, a test can automatically bring up only those dependent components required to perform testing.
It improves the quality of your code by reducing coupling between classes.
If a class instantiates an instance of another class, then there is a dependency directly between the two classes (=tight coupling). So for example, if Class A has-a relatoinship with Interface B, if Class A handles the instantiation of the Interface B, then Class A must specify a concrete implementation to instantiate and those classes become tightly coupled.
Lets say we have the following interface:
interface B{}
and then the following Class
class A{
private B b = new BImpl();
...
}
In the above example (without DI), Class A has an explicit dependency on BImpl, which means if you ever want to use a different implementation of B then you also have to change Class A.
DI (and loose coupling in general) aims to remove these kind of dependencies and have a code base where changes to one part of the code do not "ripple" through the entire application requiring lots of changes. The above example is pretty trivial, but if you have a medium to large size codebase with tight coupling this problem can get pretty bad.
why does wiring all the classes in centralize way
Centralized configuration is an implementation detail rather than part of DI. Guice for example can spread the configuration about a bit (I've not used Spring in anger so I can not comment on it).
why does wiring all the classes ... externally
As this allows you to change the implementation. DI is not the only way but it is the most popular. Factories and Service Locators are the main alternatives. Without some way of swapping out the implementation testing becomes near impossible.
development process (besides testing)
Testing is a very important part. It alone is a good reason to separate creation and use.
Unlike the other two methods above and direct initialization DI also makes the dependencies visible (esp. ctor injection) this can help other users of the class. By making the dependencies so visible it can be used to give you a warning when your class is doing too much (as it will require a lot of dependencies).
DI concept is independent of spring. Dependency Injection is possible even without using Spring. I.e. manually injection of dependency is also possible.
Please refer java example given on wiki:- http://en.wikipedia.org/wiki/Dependency_injection#Manually_injected_dependency
DI main purpose is loose coupling.
Spring provides IOC (Inversion Of Control). When we use spring to inject dependency using the Spring IOC, we get features like:
1) Loose coupling, reduce time to add new feature. Code to interface will provide this. Add new service which complies to interface and which can be replaced in bean configuration.
2)No need to change code/compile required while changing dependency.
3)Easier and fast testing. Hence, can cover more cases in same time frame which leads to good product.
4) Spring provides lots of different templates to make developers life easier. These all templates are using DI/Ioc concept. Leads to faster development cycle. Such templates are available for batch processing, JMS, JMX, JDBC operations and many more.