Is it possible to tell Guice that it's not necessary to inject all constructor arguments? For example, I have a constructor Foo that takes two args of types Bar and Baz. All of them are optional in my system: they may
both present
both missing
only Bar present
only Baz present.
That said, it depends on other modules providing these bindings. I want to get something like this:
class Foo {
private final Bar bar;
private final Baz baz;
#Inject(optional = true)
public Foo(#Nullable Bar bar, #Nullable Baz baz) {
this.bar = bar;
this.baz = baz;
}
}
But I can't really use optional with constructors. Is there a way to do that?
I think the preferred Guice pattern for this is:
public class HolderPatter {
static class Bar {
#Inject Bar(BarDependency dependency) {}
}
static class Baz {
#Inject Baz(BazDependency dependency) {}
}
static class BarHolder {
#Inject(optional=true) Bar value = null;
}
static class BazHolder {
#Inject(optional=true) Baz value = null;
}
static class Foo {
private final Bar bar;
private final Baz baz;
#Inject
public Foo(BarHolder bar, BazHolder baz) {
this.bar = bar.value;
this.baz = baz.value;
}
}
}
Note that this will also allow you to specify sane default values...
The latest version of Guice recently added OptionalBinder which works better than the #Inject(optional=true) method and also adds several advanced features.
See also the thread where OptionalBinder was announced.
Related
So, I have a class with the following constructors:
public SomeClass() {
this.foo = new Foo();
this.bar = new Bar(foo); // Bar construction requires foo
}
public SomeClass(Foo foo, Bar bar) {
this.foo = foo;
this.bar = bar;
}
Now, I would like to reutilize the second constructor by changing the default constructor for something like:
public SomeClass() {
Foo = new Foo();
this(foo, new Bar(foo));
}
But this doesn't work as I'm getting
Error:(24, 21) java: call to this must be first statement in constructor
Note that I don't want to have 2 separate instances of foo.
Any ideas how to solve this scenario?
In order to use a this constructor, it must be the first line of the constructor. Something like,
public SomeClass() {
this(new Foo());
}
public SomeClass(Foo foo) {
this(foo, new Bar(foo));
}
Note: You can make the SomeClass(Foo) constructor private if you want to prevent outside calls.
At work I came across the following design in a java project:
Consider interfaces Foo, Bar, and Baz as follows:
interface Bar { public int a(); }
interface Baz { public int b(); }
interface Foo extends Bar, Baz { public int c(); }
Now, consider class FooImpl:
public class FooImpl implements Foo {
private Bar bar;
private Baz baz;
public int a() {
return bar.a();
}
public int b() {
return baz.b();
}
public int c() {
return 0;
}
}
What are the use cases for this kind of class hierarchy? It seems to me that this introduces a lot of boilerplate and does not add much in terms of abstraction, other than breaking up what could be a large file into smaller files.
It allows things like this:
Foo foo = new FooImpl();
useBar(foo);
public void useBar(Bar bar) {
bar.a();
}
Whether this is useful depends on the real context. Your example code with classes and methods with meaningless names does not support a rational judgement.
The other thing to note is your FooImpl is actually implemented as some kind of wrapper for Bar and Baz instances. That's not (strictly speaking) an interface design issue.
I think it's a workaround for multiple inheritance (which is not allowed in Java). You're not showing implementations for Bar and Baz, but let's suppose they exist:
public class BarImpl implements Bar {
#Override
public int a() {
return 1;
}
}
public class BazImpl implements Baz {
#Override
public int b() {
return 2;
}
}
You neither have told us how Bar and Baz attributes are instantiated and set to FooImpl, because, if executed as stated in your question, you'll get a NullPointerException both in FooImpl.a() and FooImpl.b(). Again, let's imagine how this could be achieved:
public class FooImpl implements Foo {
private Bar bar; // better if final
private Baz baz; // better if final
// Constructor to properly initialize bar and baz
public FooImpl(Bar bar, Baz baz) {
this.bar = bar;
this.baz = baz;
}
#Override
public int a() {
return bar.a();
}
#Override
public int b() {
return baz.b();
}
#Override
public int c() {
return 0;
}
}
Wiring everything up:
Bar bar = new BarImpl();
Baz baz = new BazImpl();
Foo foo = new FooImpl(bar, baz);
int one = foo.bar(); // 1
int two = foo.baz(); // 2
In a way, FooImpl is "inheriting" from both BarImpl and BazImpl, though this is achieved by means of delegation.
To do this is really just redirecting fooimpl using its propertie's(bar and baz) "a" method and "b" method
If I have the following class, Foo, where Bar is also a class:
public class Foo {
private Bar baz;
public Foo() {
}
}
Am I right in thinking that if I initialise baz where it is declared I will have an aggregate relationship between Foo and Bar and if I initialise baz in Foo's constructor I will have a composite relationship? Like this:
Aggregate (I think this is probably incorrect?):
public class Foo {
private Bar baz = new Bar();
public Foo() {
}
}
Composite:
public class Foo {
public Foo() {
baz = new Bar();
}
}
I'm a little new to Java, and seeing as everything is a class, I'm having difficulty visualising how (in particular) the aggregate relationship works unless I make baz static. If I create baz somewhere else and pass it in to the constructor of Foo, then won't baz just be a composite of some other class? Bit confuzzled.
Try reading more about the dependency injection. It's what you describe in your last sentence. Its a pattern that removes hard-coded dependencies as in both of your examples, but this job is delegated to a higher-level authority.
You would get something like:
public class Foo {
private Bar baz;
public Foo(Bar baz) {
this.baz= baz;
}
}
The actual instance of baz can be changed in both compile and runtime.
The actual composition means that class Bar has no meaning (or value) without the class Foo, and it cannot exist without the Foo, - Bar "is a part of" Foo. An example would be: an IMEI number is a part of the phone.
The aggregation tells that Foo only owns the Bar, - Bar "has" Foo. An example would be: a battery is a part of the phone. Other devices that are not phones could also have batteries.
These two concepts don't have much to do with the way you code it.
Composition
final class Car{
private final Engine engine;
Car(EngineSpecs specs) {
engine = new Engine(specs);
}
void move() {
engine.work();
}
}
Aggregation
final class Car {
private Engine engine;
void setEngine(Engine engine) {
this.engine = engine;
}
void move() {
if (engine != null)
engine.work();
}
}
I have a factory as below,
public final class Application {
private static IFoo foo;
public static IFoo getFoo(String bar)
{
// i need to inject bar to the constructor of Foo
// obvious i have to do something, not sure what
Injector injector = Guice.createInjector();
logger = injector.getInstance(Foo.class);
return logger;
}
}
This is the Foo definition:
class Foo
{
Foo(String bar)
{
}
}
OK. I m not sure how I can pass this parameter to Foo constructor with Guice?
Any ideas?
All the "Guice Constructor Parameter" answers seem to be incomplete in some way.
Here is a complete solution, including usage and a visual:
interface FooInterface {
String getFooName();
}
// Annotate the constructor and assisted parameters on the implementation class
class Foo implements FooInterface {
String bar;
#Inject
Foo(#Assisted String bar) {
this.bar = bar;
}
// return the final name
public String getFooName() {
return this.bar;
}
}
// Create a factory interface with a create() method that takes only the assisted parameters.
// FooFactory interface doesn't have an explicit implementation class (Guice Magic)
interface FooFactory {
Foo create(String bar);
}
// Bind that factory to a provider created by AssistedInject
class BinderModule implements Module {
public void configure(Binder binder) {
binder.install(new FactoryModuleBuilder()
.implement(FooInterface.class, Foo.class)
.build(FooFactory.class));
}
}
// Now use it:
class FooAction {
#Inject private FooFactory fooFactory;
public String doFoo() {
// Send bar details through the Factory, not the "injector"
Foo f = fooFactory.create("This foo is named bar. How lovely!");
return f.getFooName(); // "This foo is named bar. How lovely!"
}
}
Lots of helps here: https://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/assistedinject/FactoryModuleBuilder.html
What you are probably looking for is to use a Guice factory. Particularly easy with the AssistedInject functionality, but they have a manual example at the top of the page. The short of it for the manual example is that you get the factory under non-static getFoo method that you pass whatever parameters to that you need and build the object from there.
This won't work directly if you have method interception in Foo, but it will work in many other cases.
To use AssistedInject, which to me has somewhat cleaner semantics and means less manual wiring, you'll need the guice-assistedinject extension in the classpath, then when creating Foo (well, FooImpl, we should be using interfaces):
#Inject
public FooImpl(#Assisted String bar)
{
this.baz = bar;
}
Then you create a FooFactory interface:
public interface FooFactory {
public Foo create(String bar);
}
Then in your guice module:
install(new FactoryModuleBuilder()
.implement(Foo.class, FooImpl.class)
.build(FooFactory.class));
You can check out the javadoc for FactoryModuleBuilder for examples with more complex factories.
I know that this is old thread but I just hit the issue myself today.
I only need two or maximum three different instances of 'Foo' and I really didn't want to write all the bolierplate code of Factory.
With a little googling I found this Stubbisms – Tony’s Weblog I would suggest this solution which is perfect if you know exactly what instances you need.
In Guice module:
bind(Foo.class).annotatedWith(Names.named("firstFoo")).toProvider(new Provider<Foo>() {
#Override
public Foo get() {
return new FooImpl("topic A");
}
});
bind(Foo.class).annotatedWith(Names.named("secondFoo")).toProvider(new Provider<Foo>() {
#Override
public Foo get() {
return new FooImpl("topic B");
}
});
Or in java 8:
bind(Foo.class).annotatedWith(Names.named("firstFoo")).toProvider(() -> new FooImpl("first"));
bind(Foo.class).annotatedWith(Names.named("secondFoo")).toProvider(() -> new FooImpl("second"));
And in constructor of your service where you need Foo instances:
#Inject
public MyService (
#Named("firstFoo") Foo firstFoo,
#Named("secondFoo") Foo secondFoo) {
}
And Foo in my case:
public class FooImpl implements Foo {
private String name;
public FooImpl(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
Hope it helps someone.
If this class is a factory, it should be a Guice-managed object, having a non static getFoo method, and the getFoo method would just use
new Foo(bar)
Not every class needs to be instantiated by Guice.
Also see AssistedInject, to avoid creating this factory yourself and let Guice create one for you.
Although this isn't a direct answer to what you're asking, hope it helps. I was trying to understand where the constructor parameters are being passed earlier. If they are custom classes, they should be bind-ed in the module.
Class CustomHandler {
private Config config;
#Inject
CustomHandler(Config config) {
this.config = config;
}
public void handle() {
// handle using config here
}
}
Binding:
class Module extends AbstractModule {
bind(Handler.class).to(CustomHandler.class);
bind(Config.class).to(CustomConfig.class);
}
Injection:
CustomHandler handler = injector.getInstance(CustomHandler.class);
handler.handle();
I was looking to implement an interface on a package-private java class, but I am having some difficulty achieving this. Below is an example.
class Foo
{
String something(String str)
{
return ""str+"!";
}
}
public interface Bar
{
String something(String str);
}
What is the best approach here? My end goal is to implement the Bar interface on the Foo class. I am hoping to be able to cast Foo as Bar: (Bar)Foo
The Bar interface and the Foo class are in separate packages. Is there a way to do this?
Please advise.
You can't. The point of having the package level access it to precisely avoid seeing that class outside. What you can do however ( granted Foo is not final ) something like this:
C:\>type *.java
//Foo.java
package foo;
class Foo {
String something( String s ) {
return s + "!";
}
}
//Bar.java
package bar;
public interface Bar {
public String something( String s );
}
//Baz.java
package foo;
import bar.Bar;
public class Baz extends Foo implements Bar {
// make sure you're overriding
#Override
public String something ( String s ) {
return super.something( s );
}
}
//Use it: Main.java
package bar;
import foo.Baz;
class Main {
public static void main( String ... args ) {
Bar bar = new Baz();
System.out.println( bar.something("like this?"));
}
}
C:\>java bar.Main
like this?!
Da da!
The trick is to define the child in the same package as the parent so you can create a public version of it.
I hope this helps.
When you doesn't have control on a class but you want to make it look like an API that you have, then you Adapt it to fit your needs. Hint: Adapter Pattern
Foo needs to implement Bar
protected class Foo implements Bar
Also, I think Foo.something needs to be public in order to implement Bar.something
Side Note: While it was probably just as an example,
return ""str+"!";
should be:
return str + "!";
If Foo is package private, and you don't have access to the source, just the classfiles and/or the jar containing Foo.class, there's not much to do -- something that is package private is invisible to classes in the default package (where there is no package specified) and other packages.
You'll need to use inheritance or composition if you don't have access to the source code of Foo.
// By logically including your code in the package containing Foo,
// you can now access it. If Foo belongs to the default package, sorry.
// This also doesn't work if the package is sealed.
package where.foo.resides;
public interface Bar {
String something(String s);
}
// Inheritance
public class FooBar extends Foo implements Bar {
public String something(String s) {
return super.something(s);
}
}
// Composition
public class ComposedFooBar implements Bar {
private final Foo delegate;
public ComposedFooBar(Foo delegate) {
this.delegate = delegate;
}
public String something(String s) {
return delegate.something(s);
}
}
You can try using bytecode injection with BCEL or ASM and setting the interface at runtime. It's tricky, though.
There might also be a way to change interaces with reflection, but I doubt it.
Private is there for a reason.