Guice injector inside a thread - java

I have a doubt using Guice. I have a class that I call Main that is constructor injected using Guice and a method that every time that is called creates an o thread object of class AppThread. AppThread is a private class inside Main. The problem is that inside the execution of the thread I want to create an object of class ClassX. This object is constructor injected using Guice. I don't know what's the best form to inject the objects of ClassX. My first solution is inject the Injector inside Main and inside the thread use the injector to inject the objects of class ClassX.
Does exists a cleaner approach to inject the dependences inside the thread?
Thanks

Instead of having your own subclass of Thread (which is discouraged anyway) you should write your "thread code" as a regular object that implements Runnable. Your Main class should inject this class (or you can actually inject a Provider<MyRunnable> if you need to instantiate an unknown number of them). Then your Main class can create a new Thread(myRunnable) and it should all fit together nicely.
public class MyMainClass {
#Inject
MyMainClass(Provider<MyRunnable> runnableProvider) { ... }
public void spawnThread() {
new Thread(runnableProvider.get()).start();
}
}
public class MyRunnable implements Runnable {
#Inject
MyRunnable(ClassX myX) { ... }
public void run() {
... do work ...
}
}

Related

What is proper way to create objects inside method using Guice

What is proper way to create objects inside method of a Singleton object using Guice.
If I have some code like this below, what is a proper way to create instances of Class2?
Class1 is singleton and need to create one new instance of Class2 everytime search is called (so I can not inject it with constructor field...) I will reorganize code if needed.
#Singleton
final class Class1 {
#Inject
private Class1(...){...}
public Class2 search(...){
Class2 newInstance=...
return newInstance;
}
}
I guess I found it.
Need to use providers for such instances.
Obtain class provider in constructor and use provider.get to obtain instances.
Something like:
#Singleton
final class Class1 {
Provider<Class2> p;
#Inject
private Class1(Provider<Class2> pParam;...){
p=pParam;
...
}
public Class2 search(...){
Class2 newInstance=p.get();
return newInstance;
}
}

Is there something like #PostConstruct in plain java?

I have an class A and B like this:
public static class A {
public A() {
System.out.println("A");
}
public void init() {
System.out.println("RUN AFTER CONSTRUCTOR");
}
}
public static class B extends A {
public B() {
System.out.println("B");
}
}
public static void main(String[] args) {
new B();
}
I want that A and all subclasses of A run a piece of code AFTER the constructor has finished.
Is it possible without adding Spring/AspectJ or something like that?
No. Plain Java doesn't provide similarly hook methods.
#PostConstruct available in bean containers was initially designed to perform an init processing after dependency injection is done.
As the container performs for you the instantiation (and the destruction) of the beans, it has so a way to execute code after their instantiation (or before their destruction : #PreDestroy).
But i don't want to repeat it in every subclass, and it should be
called after even the subclass constructor has finished
If each constructor invocation of the hierarchy has to perform a specific processing, you have to specify that in each class or base class.
As #DavidBrossard said, on Vanilla Java, you can call init() at the end of the constructor, to execute like a #PostConstruct

Passing one instance of an object to different classes without using static or singleton

I am trying to figure out a way to pass one instance of the same class to multiple classes so I am able to build an object. The problem is it cannot be static or use singleton because many users will be hitting the application at the same time and I may run into other issues. Are there any design patterns that would work best with this scenario or if there is some way to use global variables in java? I am trying implement this with an existing rest service that was not designed very well.
public class OneInstanceOf
{//I want to build this map object without static
private Map<String, String> mapIwantToBuild = new HaspMap<String, String>();
public void methodIwantToCall(String name, String value)
{mapIwantToBuild.put(name, value)
}
The common pattern for you task is dependency injection. You can use spring framework for that task.
1.Create configuration with your bean:
#Configuration
public class YourConfiguration {
#Bean
public OneInstanceOf oneInstanceOf {
return new OneInstanceOf();
}
}
2.Inject your bean whatever you want (simplest - use autowiring):
#Component
public class Client1 {
#Autowire
private OneInstanceOf oneInstanceOf;
public void someMethod() {
oneInstanceOf.methodIwantToCall();
}
}
Spring will insure single instance of oneInstanceOf will be injected in all clients.
U can create a setter with parameter of instance class variable, in every class in which you want to pass the instance. Then create a method in one of the classes that calls setter of all those classes and pass parameter instance as parameter to that method.
Like below.
class A{
B b = new B;
set(B b){
C.setB(b);
D.setB(b);
E.setB(b);
}
}

Guice: instantiating a singleton before creating the module

Is it possible to instantiate and assign a singleton to a reference with Guice before creating the Module and pass that instance to the Module constructor be bound during configuration?
Here is an example of what I mean:
I have a method that allows me to create objects depending on a custom implementation of an interface which is being passed in constructor as an Optional (if the user won't provide a custom implementation, we will use the default one), which is being done by binding the interface to that particular implementation in the Module class. :
public static MyClass createMyClassObject(Optional<SpecialInterface> customSpecialInterfaceObject) {
SpecialInterface specialInterfacebject;
if(customSpecialInterfaceObject.isPresent() {
specialInterfaceObject = customSpecialInterfaceObject.get()
} else {
/* here I would like to bind it to an instance of the DefaultSpecialInterfaceObject but can't really do something like:
Injector injector = Guice.createInjector(myClassModule);
DefaultSpecialInterface instance = injector.getInstance(DefaultSpecialInterface.class);
as the module is yet to be created */
}
MyClassModule myClassModule = new MyClassModule(specialInterfaceObject);
Injector injector = Guice.createInjector(myClassModule);
return injector.getInstance(MyClass.class);
}
I'm currently using classes instead of instances to solve this problem, such as in the example below, but I don't quite like this solution. Would be happy to see a better way of doing it:
private static Class resolveSpecialInterfaceObject(Optional<SpecialInterface> customSpecialInterfaceObject) {
Class specialInterfaceObjectClass;
if (customSpecialInterfaceObject.isPresent()) {
specialInterfaceObjectClass= customSpecialInterfaceObject.get().getClass();
} else {
specialInterfaceObjectClass = DefaultSpecialInterface.class;
}
return specialInterfaceObjectClass;
}
public abstract class MyClassModule extends AbstractModule {
private final Class<SpecialInterface> specialInterfaceObjectClass;
public MyClassModule(Class<SpecialInterface> specialInterfaceObjectClass) {
this.specialInterfaceObjectClass= specialIntefaceObjectClass;
}
#Override
protected void configure() {
bind(SpecialInterface.class).to(specialInterfaceObjectClass);
}
}
Edit, from a comment below:
one more thing- didn't want to make the question too long; actually, I also want to perform another operation on the resulting instance of SpecialInterface, but only if it is the instance of DefaultSpecialInterface and I don't think it should be done in the Module. I was thinking if I could just have this bean up and running before, such as in Spring, so I could just pass it to the Module, but also use it in another method call before?
Can you take the whole Optional and use bind(...).toInstance(...)?
public static MyClass createMyClassObject(
Optional<SpecialInterface> customSpecialInterfaceObject) {
MyClassModule myClassModule = new MyClassModule(customSpecialInterfaceObject);
Injector injector = Guice.createInjector(myClassModule);
MyClassFactory instance = injector.getInstance(MyClassFactory.class);
return instance.createMyClassObject();
}
class MyClassModule extends AbstractModule {
private final Optional<SpecialInterface> customObject;
MyClassModule(Optional<SpecialInterface> customObject) {
this.customObject = customObject;
}
#Override public void configure() {
if (customObject.isPresent()) {
// Singleton by necessity: Guice doesn't know how to create another one.
bind(SpecialInterface.class).toInstance(customObject.get());
} else {
// Default scoped. Add ".in(Singleton.class)" if necessary.
bind(SpecialInterface.class).toInstance(DefaultSpecialInterfaceClass.class);
}
}
}
If you want to perform additional initialization on DefaultSpecialInterface and nothing else, you have a number of options:
If some kind of initialization is important for all implementations and likely too heavy to put into a class constructor, add an initialize method on your SpecialInterface. Make the custom one a no-op, and implement it for DefaultSpecialInterface.
If the initialization is unique to DefaultSpecialInterface, I see no reason why it shouldn't be in the Module. Write a #Provides method or bind to a Provider<SpecialInterface> that creates and initializes DefaultSpecialInterface correctly.
If your real goal is to keep the business logic out of a Module, you can do so by extracting it into a free-standing Provider or DefaultSpecialInterfaceFactory that is responsible for that.
Remember, Guice is responsible for feeding fully-constructed objects into your object graph, and that means that injecting a SpecialInterface should get a ready-to-use implementor of the SpecialInterface general contract. If Guice needs to perform some initialization to make that happen, it's not unreasonable to have it do so, and a Module isn't a bad place to do it.

Appropriate way to pass instance of class to other classes (Java)

I have a main class which has a number of instance related methods that are often needed in other classes and I often find myself passing an instance of the main class in the constructor. I often find this goes several layers deep with classes having instances of the main class that has been copied from instance to instance which I can't imagine is good for memory usage.
Is there a way to do this without having to pass the instance in the constructor or a method or at least a way to reduce the memory that is used by the instances of the main class.
To make it clear I am not looking for static methods, it is designed to be able to have more than one instance of the main class.
Example code:
public class Main {
public Main() {
Class2 class2 = new Class2(this);
}
public void someMethod() {
//Do something
}
}
public class Class2 {
private final Main instance;
public Class2(Main instance) {
this.instance = instance;
Class3 class3 = new Class3(instance);
}
}
public class Class3 {
private final Main instance;
public Class3(Main instance) {
this.instance = instance;
instance.someMethod();
}
}
You can use Dependency Injection Design Pattern.
Dependency-Injection-Design-Pattern
Spring, Google Guice and Java EE CDI frameworks facilitate the
process of dependency injection through use of Java Reflection API and
java annotations. All we need is to annotate the field, constructor or
setter method and configure them in configuration xml files or
classes.
You could also use dependency injection to pass on the dependent attributes or objects to required classes.
One such popular framework is Google Guice.
You could make methods like someMethod() in the Main class static, or if that's not possible, make the Main class itself a singleton.
Example of the former approach:
public class Main {
public Main() {
Class2 class2 = new Class2(this);
}
public static void someMethod() {
//Do something
}
}
Now you don't have to pass an instance of Main around any more, because other classes can just call Main.someMethod() directly.

Categories