I saw this line in Nexus OSS code ...
#Inject
public ReleaseRemoverTask( final ReleaseRemover releaseRemover )
{
this.releaseRemover = checkNotNull( releaseRemover );
}
the above is found in https://github.com/sonatype/nexus-oss/blob/master/components/nexus-core/src/main/java/org/sonatype/nexus/maven/tasks/ReleaseRemoverTask.java
But ReleaseRemover.java is an interface .
There is no use in interface here , so only the implementation should be passed during runtime ..This only makes sense ..
So I confirmed it by debugging , that the implementation is called .The implementation class was DefaultReleaseRemover.java .
To support my argument I wrote a plugin for nexus and I wrote an implementation for ReleaseRemover .
Even that was picked up ...
How is this done ?
Internally they are using Google Guice ..
Is Guice doing this job of passing the implementations inside this function ?
Is this the property of frameworks like Google Guice ?
If all implementations are passed like this , can I prevent an implementation from being passed ?
you question is not clear for me. What do you want to achieve? What means can I prevent an implementation from being passed ? what you want to pass instead? Null or your implementation?
You are right about that Nexus OSS uses Google Guice as Dependency injection framework. To bind an implementation to some interface you have to create modules where you say something like this:
bind(ReleaseRemover.class).to(DefaultReleaseRemover.class);
As you see in DefaultReleaseRemover there are another injections and they very likely stuck up. So the injected implementation in DefaultReleaseRemover contains another injections and so on.
The DefaultReleaseRemover is annotated as #Singleton which means there is only one instance of DefaultReleaseRemover class for whole injector.
Well, you have your interface and implementation and your module with bindings. Now you need to create Guice Injector and use it to create all objects for you.
For Nexus OSS you can find Guice Injection entry point at https://github.com/sonatype/nexus-oss/blob/de6a606372349283f78aeaa498e9a70d4dd967b1/components/nexus-webapp/src/main/java/org/sonatype/nexus/webapp/WebappBootstrap.java line 118
Guice.createInjector(your modules...);
See, you will provide all modules you want to install to the Guice Injector. Be aware there could be some sub modules installed inside modules. You dont have to explicitly pass it into createInjector function. So, if you want to change some Guice bindings it's good start to dig from there.
UPDATE:
I don't know the mechanics. But you have to bind your implementation in some Module.configuration() as
bind(ReleaseRemover.class).annotathedWith(Names.named("custom")).to(MyCustomReleaseRemover.class);
The module should be not PrivateModule:)
Then you will pass you CustomReleaseRemover as
#Inject
public ReleaseRemoverTask( final #Named("custom") ReleaseRemover releaseRemover )
I would direct you more straight forward, but I have no idea how it works inside Nexus OSS. Maybe somebody could you help with that part.
Related
So after a lot of searching and banging my head against a brick wall, I figured it was easier to put this question out there to see if anyone can help.
To set the backstory to this question:
I'm currently writing a custom Java framework for a project, which has a small internal DI system that just scans through a class, looks for any fields annotated with #Dependency (provided by the annotations package from my framework) and uses its internal Map to inject instances into those fields.
For reference, this framework is used by client code in the following way:
Client creates a new Singleton instance of the core manager
Client builds classes that extend a Base class and implement whatever logic they desire using the framework
Client registers their class with the manager (essentially: Manager#register(Class<? extends BaseClass)
The manager will then instantiate the client's class and perform its dependency injection as mentioned above
I'm currently working on building Guice support into this framework so that Clients who are using Guice in their code can get their dependencies from Guice if they so desire. I'd ideally like this to work alongside the framework's internal DI, however this is not a hard requirement. To note, the framework itself does not use Guice.
I've currently got two options on my hands from what I can tell:
Option 1: Get the client to pass their Guice injector into my Guice Handler class and let Guice create the classes via injector.getInstance
Option 2: Let the client's Guice injector create my Guice Handler class and have a MembersInjector injected into the handler to then call injectMembers on the class instances where required.
Option 1 from what I can tell is a bad approach, for reasons described here: (https://github.com/google/guice/wiki/InjectingTheInjector)
So I'm currently working towards Option 2. This would require the client code to do something like:
Manager manager = new Manager();
Injector injector = Guice.createInjector(new ClientModule();
manager.enableGuiceSupport(injector.getInstance(GuiceHandler.class) Or:
GuiceHandler guiceHandler = new GuiceHandler();
injector.injectMembers(guiceHandler);
manager.enableGuiceSupport(guiceHandler);
Obviously Guice needs to deal with the GuiceHandler class so that I can get the MembersInjector injected.
Looking at this, whilst a valid solution to the problem, its adding a requirement on the client that feels slightly labored. The aim of the framework is to reduce what the client code needs to do, not add to it.
So my question boils down to this:
Is my approach to Option 2 here a good way to move forward and I just accept that the client needs to "bootstrap" the GuiceHandler?
Or alternatively, is there just a better way to achieve the goal of adding Guice support?
Any thoughts, suggestions and constructive criticism is welcome!
(To everyone who's taken the time to read through all this to see if you can help, have a cookie: 🍪. I really appreciate your time!)
When i generate code for Spring from my swagger yaml , usually controller layer is generated using delegate pattern , such that for a single model three files are generated . For example , if i defined a model named Person in my swagger/open API yaml file , three files get generated as :
PersonApi (interface that contains signatures of all person operations/methods)
PersonApiDelegate ( interface that provides default implementation of all PersonApi methods . Meant to be overriden )
PersonApiController (Which has a reference to PersonApiDelegate so that any implementation can override and provide custom implementation)
My question is for anyone who is familiar with building swagger/openapi generated code based apis that what is the significance of having such a pattern , instead of just exposing your service endpoints using a PersonController class , and not going through a PersonApi interface and then to a PersonApiDelegate and finally exposing the service through a PersonApiController ?
What is the valuable design extensibility we gain through this pattern ? I tried to find information from other resources on internet , but couldn't find a good answer in context of swagger first API development approach . Any insights on this will be really helpful .
First of all a clarification: as already mentioned in a comment, you are not forced to use the delegation. On the contrary, the default behavior of the Spring generator is to not use the delegation pattern, as you can easily check in the docs. In this case it will generate only the PersonApi interface and PersonApiController.
Coming to your question, why using delegation?
This allows you to write a class that implements PersonApiDelegate, that can be easily injected in the generated code, without any need to manually touch generated sources, and keeping the implementation safe from possible future changes in the code generation.
Let's think what could happen without delegation.
A naive approach would be to generate the sources and then write directly the implementation inside the generated PersonController. Of course the next time there is a need to run the generator, it would be a big mess. All the implementation would be lost...
A slightly better scenario, but not perfect, would be to write a class that extends PersonController. That would keep the implementation safe from being overwritten during generation, but would not protect it from future changes of the generation engine: as a bare minimum the implementation class would need to implement the PersonController constructor. Right now the constructor of a generated controller has the following signature PersonApiController(ObjectMapper objectMapper, HttpServletRequest request), but the developers of the generator may need to change it in the future. So the implementation would need to change too.
A third approach would be to forget completely about the generated PersonApiController, and just write a class that implements the PersonApi interface. That would be fine, but every time the code is generated you would need to delete the PersonApiController, otherwise Spring router will complain. Still manual work...
But with the delegation, the implementation code is completely safe. No need to manually delete stuff, no need to adapt in case of future changes. Also the class that implements PersonApiDelegate can be treated as an independent service, so you can inject / autowire into it whatever you need.
I am coming from .NET land and am doing some Java projects recently (converting parts of a .NET codebase to Java). Normally I use .NET along with Castle Windsor as my IoC container of choice and am very familiar with it. I am using the PicoContainer IoC container for a Java project and I am trying to figure out how to inject a scoped dependency into the container. By "scoped dependency", I mean a dependency whereby the result is the exact same object each time the dependency is resolved from the container for as long as the "scope" of the container is open.
In .NET land, using an IoC container such as Castle Windsor, it was trivial to register a component with a certain life cycle (Singleton, Transient, Scoped, etc.). For example, the following C# works perfectly as expected.
// C# CODE //
IWindsorContainer container = new WindsorContainer();
container.Register(Component
.For<Foo>()
.ImplementedBy<FooImpl>()
.LifestyleScoped()
);
using (container.RequireScope())
{
Foo foo1 = container.Resolve<Foo>();
Foo foo2 = container.Resolve<Foo>();
Console.WriteLine(foo1 == foo2); // Will print true
Console.WriteLine(foo1.Equals(foo2)); // Will print true
}
public interface Foo
{
}
public class FooImpl : Foo
{
}
However, in Java land, using an IoC container like PicoContainer, it appears there is not a way to implement such behavior which I find rather odd.
// JAVA CODE //
PicoContainer container = new DefaultPicoContainer();
container.addComponent(FooImpl.class);
// FooImpl implements an interface called "Foo" (for clarity & brevity)
Foo foo1 = container.getComponent(Foo.class);
Foo foo2 = container.getComponent(Foo.class);
// How to "scope" PicoContainer"?
// It appears the default behavior of DefaultPicoContainer is "scoped"...
// I could not find any documentation clarifying one way or another though
System.out.println(foo1 == foo2); // Should print true (most likely), for reference equality, but it does not.
System.out.println(foo1.equals(foo2)); // Should print true, for object equality, but it does not.
public interface Foo
{
}
public class FooImpl extends Foo
{
}
I am sure it must have a feature like this as I cannot imagine someone using an IoC container and wanting every single dependency to be either transient or a singleton only.
Now, before posting this question, I did thoroughly consult the documentation at the following links as well as Google for solutions, but nothing seemed to be helpful:
http://picocontainer.com/lifecycle.html
http://picocontainer.com/javadoc/core/org/picocontainer/DefaultPicoContainer.html
http://picocontainer.com/javadoc/core/org/picocontainer/lifecycle/DefaultLifecycleState.html
It appears there is no such lifestyle (or associated API) option to allow for scoped dependencies in PicoContainer. Some ideas I can think of to solve the problem are either a temporary container (or child container of a master container) that holds "temporary singletons" that act like scoped dependencies and once the calling code finishes with the child container it will call some kind of "dispose" method on the child container holding the "temporary singletons" and flush them all out. However, this seems inelegant and rather "hacky" as far as I can see.
The other solution may reside in the "start" and "stop" API's of PicoContainer, but these do not make sense to me as I do not understand the idea of an IoC container "starting" and "stopping" but rather just "existing" (or not). Also, the documentation is unclear if the various dependencies would need to implement such methods/API's. That sort of use case seems ... unintuitive? Or rather like we are encouraging coupling and leaking abstractions/NFC's into dependencies. I doubt this is what those API's are intended for, so I may be on the wrong track here.
P.S. I am not "married" to the idea using PicoContainer as the IoC container of choice for this project. I am open to other options if they can achieve IoC container functionality. I did some light initial investigation of "Guice" but it seemed to not be a "Container" in the traditional IoC container sense but rather a library with a limited injector and depends completely on annotations for dependency resolution. I am looking for something closer to what one would expect with a traditional IoC container such as Castle Windsor for example.
Thanks for any insight or assistance!
Say I have a Module structure like this:
Root
|--SubModuleA
|-BaseModule
|--SubModuleB
|-BaseModule
SubModuleA and SubModuleBare intended to be used seperatly but also in one application like in this example. And both install the same BaseModule.
Guice allows to declare the same bindings several times if they are exactly the same. In another SO-thread this is referred to as "binding de-duplication".
This works fine for simple bindings, but using a FactoryModuleBuilder in the BaseModule results in a CreationException complaining that
"A binding to ... was already configured at [...]FactoryModuleBuilder$1.configure()"
I checked, that the binding really is declared only in one Module. And removing the binding results into an error stating that the binding is missing. So I assume that it is not possible to declare the same binding more than one time using a FactoryModuleBuilder. Is that true? Is there a way around this?
Yes, you can get around this by instead doing
Root
|--BaseModule
|--SubModuleA
|--SubModuleB
All modules together define the registered bindings of the injector. Only in special cases should it be actually necessary to install another module inside of a module, apart from readability.
I am trying out the toothpick DI library and I seem to miss something crucial.
I created the following test project on github where I tried to make a smallest possible use case for my understanding issue.
There you will find the ApplicationModule where I try to inject everything I need in my "root" module. As you can see there, I have twice scope.installModules(module) because my PlainPojo depends on the Application instance. If I do not do the first installModule call, I have no application instance in the scope. I could, as mentioned in the comment, pass the application instance as a parameter but I thought that I can remove them when I use DI?
The second class that causes troubles is the SimpleTest class. If I do not call the inject() method in the constructor, the PlainPojo member will not be injected. I also tried to use a third time the installModules() in the ApplicationModule after binding the PlainPojo but that does not help.
Am I so wrong to assume that an #Inject on a member is enough to automatically inject it when it is available in the scope and that the order of binding is enough to make previous bindings available without installing in between (like done in ApplicationModule)?
If I can provide anything more to make my issue(s) understandable please leave a comment.
Thanks in advance!
Toothpick can only inject dependencies automatically when it creates the instance of the depended object itself (e.g it is annotated with #Singleton or there is a direct binding for the class).
Otherwise you have to manually call Toothpick.inject, just like you do in SimpleTest. There is no way for TP to know when you call the constructor of PlainPojo.
You could just use
module.bind(PlainPojo.class);
module.bind(SimpleTest.class);
and maybe scope them as singletons if needed.