I would like to know what is the best practice for the following problem:
I want have 2 instances of some class (BlockingQueue in particular) to inject them into my other classes. Each of these instances is configured separately (in particular, they have different capacities) and they don't support automatic injection via #Inject annotation. The 2 instances are the only 2 instances of that class in the application.
Now, I know that I can use binding annotations to distinguish between the two instances and use instance binding to actually bind to a single instance. But the problem is that I also need to configure these two objects and I want to obtain configuration dependencies from Guice. What do you think would be a best way to do this?
One option is to use #Provides bindings
Create a method in your guice module that provides the dependency. You can add dependencies you need to construct the object in the method signature.
#Provides
#MyBindingAnnotation
#Singleton
BlockingQueue<String> provideBlockingQueue(MyGuiceManagedConfig config){
return new LinkedBlockingQueue<String>(config.getCapacity());
}
...and they don't support automatic injection via #Inject annotation
By the way, Guice has a feature called constructor bindings, which makes it possible to bind constructors without #Inject:
try {
binder().bind(Integer.TYPE).toInstance(10);
binder().bind(new TypeLiteral<BlockingQueue<String>>() {})
.toConstructor(LinkedBlockingQueue.class.getConstructor(Integer.TYPE));
} catch (NoSuchMethodException e) {
addError(e);
}
Related
I am integrating Hystrix into SilverWare microservices platform and I want to use hystrix-javanica annotations. These annotations are meant to be applied on the actual implementation of the methods that need to be executed using Hystrix. The problem is that I need to implement a generic solution where you only have a service interface. It has to be done this way in order to let developers use annotated references to other microservices (when they implement their own service) without any need to deal with the implementation of those services.
I came up with a solution where you annotate your microservice reference with something like this:
#Inject
#MicroserviceReference
#HystrixConfiguration(MyServiceHystrix.class)
private MyService myService;
And then you implement (or extend) the service interface and put Hystrix annotations on its methods:
public interface HystrixedMyService extends MyService {
#HystrixCommand
doSomething();
}
When there is #HystrixConfiguration annotation on a field in your microservice referencing another service, SilverWare will scan the class given as a parameter of this annotation and prepare a Hystrix command for every method of the service. The command will also receive a callable with an actual method invocation which will be executed in its run() method.
My question is: Is it possible to reuse some (internal) parts of hystrix-javanica so I do not need to scan all the annotations and create those Hystrix commands myself? I can see that most of the classes are designed to be used only with AOP.
I have a spring application that uses rabbitmq-based RPCs. on the client side, I would like to generate a proxy object that delegates to the RPC based on annotated interfaces available on the classpath of the client. in a similar way, I want to be able to register exchanges, queues and consumers on the server side, based on annotated concrete classes.
the annotations i have are #RpcInterface and #RpcEndpoint, and I created a java proxy from the interfaces implemented by the RpcEndpoint.
My problem now is that I want to be able to scan the classpath for classes with these annotations and add beans for client- and server side to the application context based on that. The problem is that FactoryBean only allows instantiation of a single object, and BeanDefinitionRegistryPostProcessor requires me to add bean definitions, which isn't really possible, because on the client side, I might only have interface that cannot be instantiated.
Right now, I'm adding #Configuration classes with one #Beans method for each interface next to where the interfaces are defined, so if I add a dependency on the interface, i would also pull in the #Configuration. This feels like unnecessary code, if I could just have something that returns a bunch of instantiated beans rather than one single bean.
so, instead of:
#Bean
public Object createBlahBean() {
createProxyFor(MyInterface.class);
}
I would like to be able to do:
#Beans
public List<Object> createBlahBeans() {
List<Object> out = new ArrayList<>();
for(Class c : findAnnotatedInterfacesFromClasspath()) {
out.add(createProxyFor(c));
}
return out;
}
or similar. any pointers?
I'm working on a project and trying to bring two different 'data service' modules together into a web app (currently, the app is a desktop Swing app).
Each module has its own Guice (private) module. Each Guice module contains:
#Provides
#Inject
protected JPQLQuery provideJPQLQuery(EntityManager entityManager) {
return new JPAQuery(entityManager);
}
This is used later in the constructor of the classes that look things up from the db:
#Inject
public SomeClassThatLooksObjectsUpFromDatabase(Provider<JPQLQuery> queryProvider) {
this.queryProvider = queryProvider;
}
The 'queryProvider' is then able to execute queries.
Now, this works fine when only one of the Guice modules is installed, but once both are installed, I (predictably) get this error:
Unable to create binding for com.mysema.query.jpa.JPQLQuery. It was already configured on one or more child injectors or private modules
bound at ServiceOneGuiceModule.provideJPQLQuery()
bound at ServiceTwoGuiceModule.provideJPQLQuery()
Now, I understand why this is broken -- I'm saying that there's two Providers for the type JPQLQuery and Guice doesn't know which one to use.
Is there any way I can get Guice to separate these Providers? I would like to do this because each module has its own properly-configured Hibernate entities, and each has its own unique datasource (multiple databases in this project).
Ideally, it would involve something like somehow naming these providers and injecting them by their name (e.g. I could separately inject "ServiceOneJPQLQueryProvider" and "ServiceTwoJPQLQueryProvider"), but I haven't found any way of achieving anything like this.
(I suppose an alternative is to somehow configure Hibernate so it has all the different datasources it needs and then I'd only need one Provider for my queries, possibly, but that seems like a lot more work than what I'm describing above)
Have a look binding annotations, they're used to solve just the problem you've got.
They're recommended over using #Named because they are type-safe and will produce compilation errors and not runtime errors if you misspell them.
In short:
ServiceOne.java:
#BindingAnnotation #Target({ FIELD, PARAMETER, METHOD }) #Retention(RUNTIME)
public #interface ServiceOne {}
ServiceTwo.java:
#BindingAnnotation #Target({ FIELD, PARAMETER, METHOD }) #Retention(RUNTIME)
public #interface ServiceTwo {}
ServiceOneModule.java:
#Provides
#ServiceOne
#Inject
protected JPQLQuery provideJPQLQuery(EntityManager entityManager) {
return new JPAQuery(entityManager);
}
SomeClass.java:
#Inject
public SomeClassThatLooksObjectsUpFromDatabase(#ServiceOne Provider<JPQLQuery> queryProvider) {
this.queryProvider = queryProvider;
}
First of all, you're incorrect about #Named because providers are ubiquitous in Guice - in fact, when you create a binding like bind(...).to(...) or any other non-provider binding you're implicitly creating a provider. And it is just a shortcut for injecting providers when you inject objects directly - providers injection and direct injection are interchangeable in Guice (when you are not using special scopes like RequestScoped, but this is more like implementation detail of this shortcut). For example, even if you created #Provides method for JPQLQuery, you still can inject it directly, without a provider:
#Inject
public SomeClass(JPQLQuery query) {
...
}
Which approach to use depends on your requirements (do you need several fresh instances of JPQLQuery inside SomeClass methods?) and scopes in use (e.g. when scope of SomeClass is wider than that of JPQLQuery - for example, when SomeClass is singleton, and JPQLQuery is request scoped - sometimes provider usage is mandatory).
You're not getting what you want with #Named yet because you create #Named binding with #Provides, but still inject Provider<...> without annotation. It won't work because binding key consists both of injected type and (possibly absent) binding annotation, so if you have only bindings with assigned annotation but inject provider or type without annotation, Guice will fail. You should put #Named annotation onto the constructor parameter as well:
#Inject
public SomeClass(#Named("ServiceOne") Provider<JPQLQuery> queryProvider) {
...
}
This way it should work.
BTW, I strongly recommend against #Named. You'd better create separate binding annotation for each of your distinct binding for the same class, as described here. With custom annotations you won't have a chance to make a mistake in binding name when you inject it.
Also there is more advanced machinery for manipulating similar bindings. It is called private modules. However, you should rarely need it. It could be needed, for example, to create trees of objects which differ only in few bindings. This does not seem to be your case - binding annotations are your way to go.
I am trying to dynamically generate some set of event handlers (using com.google.gwt.core.ext.Generator subclass). The whole generation process works fine, my generated handlers accepts EventBus via setter injection (#Inject annotation) and the whole idea is that these automagically generated handlers register themselves in the (injected) EventBus under the hood. The problem is that all these handlers must be somehow instantiated. GIN does not know anything about them until they will be bound in GIN module; something like below:
bind(MyDynamicallyGeneratedHandler.class).asEagerSingleton();
The problem with this code is that I have to generate gin module also (which will contain all bind(...) instructions). It works well but I cannot install generated module (#Inject it) into another not generated module so that its bind instructions are executed (as a result of install(MyDynamicModule.class)). I tried dirty tricks with static injection and providers - all without success.
Is there any way to configure dynamically generated GIN module? Or maybe is there any way to instantiate dynamically generated handlers so that setter injection (and thus event bus registration) happens?
Here is sample code snippet:
// it is standard interface
public interace DynamicHandler {
#Inject
void setEventBus(EventBus eventBus);
}
// one of dynamically generated handlers
// where (how) to instantiate me?
public class MyHandler implements DynamicHandler {
#Inject
AnotherHandlerSpecificComponent component
void setEventBus(EventBus eventBus) {
eventBus.register(...); // register myself
}
}
Important thing to note is that all these dynamically generated handlers have some other dependencies #Injected (apart from EventBus). And these dependencies (their types) ale handler-specific (AnotherHandlerSpecificComponent in the example above). So what I need to do is to instantiate these handlers in a way that triggers GIN injection (I cannot, for example, inject dependencies manually).
Thanks in advance for any clues. I am totally stucked...
How about a Factory where you inject the dependencies for the handlers and try to instantiate and register the actual handlers (e.g. by reflection or scanning the file system?)
Is there a way to auto-cast Spring beans to the class defined in the application context XML? I'd like to avoid putting type information about the beans in 2 places.... in the xml configuration file and also in the code as a cast.
For instance, given this config file
<bean id="bean-name" class="SimpleSpringBean" scope="prototype">
<property name="myValue" value="simple value"></property>
</bean>
Can I call ApplicationContext.getBean("bean-name") in such a way as to avoid directly casting the return type to SimpleStringBean. I know I can also call ApplicationContext.getBean("bean-name", SimpleSpringBean.class) to avoid the cast itself, but I still have the type info in 2 places.
It seems that Spring can get the class info (ApplicationContext.getType) or by getting the type from the bean itself, but no way to automatically cast the type without programmer intervention.
I agree with Sii, you should avoid calling getBean as much as you can. Just wire your beans to classes that depends on them.
Still, if you have a single class that holds the application context, you can provide a wrapper generic method like the following:
class MyContextHolder{
ApplicationContext appContext;
......
#SuppressWarnings("unchecked")
public static <T> T getBean(String beanName)
{
return (T)appContext.getBean(beanName);
}
}
Then you can call it without casting
MyClass mc = MyContextHolder.getBean("myClassBean");
The answer is you shouldn't be using ApplicationContext.getBean() at all if it's possible, and bear with the one place you have to in the bootstrap code. (Generally, you should never need to use getBean() outside of your application's entry points.)
Also, what you're asking is likely impossible in the Java language at all. Casting is a compile-time feature, combined with a runtime check. The return type of getBean() simply must be known at compile time. Even if Spring can determine the type of an object, it can't change its own method signatures at runtime.
Another thing is that even if this were possible, the feature wouldn't be all that useful. Because Spring AOP is implemented using dynamic proxies, you nearly always want Spring to hand you an instance of an interface the bean implements (which could be an AOP proxy), not of the implementation class.
Another approach I also use is autowiring the bootstrapping class using:
public class Main {
#Autowired FooFacade foo;
#Autowired BarFacade bar;
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("appCtx.xml");
AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory();
Object main = bf.createBean(Main.class,
AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT,
false);
((Main) main).run();
}
private void run() {
foo.doBootstrapStuff();
bar.doMoreBootstrapStuff();
}
}
(Code done from memory. Might only work if you have the Spring context configured to process wiring annotations, in that case making setters for foo and bar should work.)
The main reason for getBean being untyped is the compatibility of Spring (up to version 2.5.x) with Java 1.4. Spring 3.0 will drop that and thus offer typed getBean method then.
Nevertheless you should avoid looking up beans directly and minimize its usage as far as possible.
What if I use Spring as an object factory that my application uses extensively.
That is, instead of writing a bunch of classes that already inherit or wrap around
known Java classes I just decide to move all that into an xml file to cut down on
lines of Java code. This will mean many lines of xml but I won't need to make
skeleton Java classes which I inject with Spring or autowire. Thus making the lines
of Java code less.
For this reason and still as I am new to Spring I have just as stated in previous
posts used static Java methods which wrap around the getBeans().
I have worked with Spring but it is still new to me so forgive my question.
"Because Spring AOP is implemented using dynamic proxies, you nearly always want Spring to hand you an instance of an interface the bean implements (which could be an AOP proxy), not of the implementation class"
So there is no way to get a dynamic proxy using getBean(), then whats the best practice if there are no interfaces and its a stand alone driver class to be executed?