creating multiple generated proxies - java

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?

Related

How to call Spring Framework repositories methods

I know that there are questions similar to this one, but none of them have helped me. I'm following along this tutorial, and the part I can't wrap my mind around is:
#SpringBootApplication
public class Application {
private static final Logger log =
LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
#Bean
public CommandLineRunner demo(CustomerRepository repository) {
return (args) -> {
// save a couple of customers
...
// more lines, etc...
What I don't understand is where the repository passed into demo comes from. I know that the Autowired annotation can do something like that, but it isn't used at all here.
The more specific reason I ask is because I'm trying to adapt what they do here to an application I'm working on. I have a class, separate from all of the persistence/repository stuff, and I want to call repository methods like save and findAll. The issue is that the repository is an interface, so I can't instantiate an object of it to call the methods. So do I have to make a new class that implements the interface and create an object of that? Or is there an easier way using annotations?
When creating a #Bean, adding the repository in the parameters of the bean is enough to wire the repos in your bean. This works pretty much like adding #Autowired annotation inside a class that is annotated as #Component or something similar.
Spring works mostly with interface, since that is simplier to wire vs wiring concrete classes.
Can you try #Repository before the declaration of class? Worked for me in a Spring MVC structure.
#Repository
public class EntityDAOImpl implements EntityDAO{
...
}
The thing to wrap your head around is a Spring Boot application at startup time aims to resolve its dependancy tree. This means discovering and instantiating Beans that the application defines, and those are classes annotated with #Service, #Repository, etc.
This means the default constructor (or the one marked with #Autowire) of all beans is invoked, and after all beans have been constructed the application starts to run.
Where the #Bean annotation comes into play is if you have a bean which does not know the values of it's constructor parameters at compile time (e.g. if you want to wire in a "started at" timestamp): then you would define a class with an #Configuration annotation on it, and expose an #Bean method in it, which would return your bean and have parameters that are the beans dependencies. In it you would invoke the beans constructor and return the bean.
Now, if you want a certain method of some class to be invoked after the application is resolved, you can implement the CommandLineRunner interface, or you can annotate a method with #PostConstruct.
Some useful links / references:
https://docs.spring.io/spring-javaconfig/docs/1.0.0.m3/reference/html/creating-bean-definitions.html
https://www.baeldung.com/spring-inject-prototype-bean-into-singleton
Running code after Spring Boot starts
Execute method on startup in Spring

Using hystrix-javanica annotations on interfaces

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.

Guice: how to get more than one #Provides for a type?

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.

Guice: Creating more than one object instance with different configurations

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);
}

Binding generated classes in gin

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?)

Categories

Resources