I want to store HashMap Object likeHashMap<String,MyClass> contextHashMap = new HashMap<String,MyClass> (); which will be accessible through out the application like as we store the object/variables in ApplicationContext of Struts.
So that I can Change or read the Data from this Variable whenever I need.
It isn’t really clear what you need but one option would be to store the data in a singleton service and inject that service wherever it is needed. That is a super simple solution.
You can also create a simple singleton Spring-bean of type Map (ConcurrentHashMap) and also inject into any Grails artefact:
resources.groovy:
beans = {
contextHashMap( ConcurrentHashMap )
}
and inject:
class ExampleController {
def contextHashMap
…
}
Related
I'd like to provide constructor arguments via Guice to new Cayenne data objects, but it looks like cayenne just uses Class.newInstance() to instantiate new instances. Is there any way to have Cayenne use a provider to get a new instance instead? I'd need it to do this, for instance, when instantiating new instances during a fetch not just when I create a new instance.
To expand a little, I have a Maven project that has all the Cayenne models and core business logic. Then I have another Maven project with the API implementation. I want to be able to configure parameters in the API project and have the model use those parameters at runtime.
So, could do it with a constructor injection or a provides method - either one is fine.
Is there any way to do this?
public class Foo extends _Foo { //_Foo extends CayenneDataObject
private final String hey;
public Job(#Inject #Named("foo-job") String hey) {
super();
this.hey = hey;
}
}
Cayenne persistent objects are not managed via dependency injection (DI). DI is appropriate for relatively small number of services, not for a potentially huge number of persistent objects.
A more idiomatic way to pass some values to an object is via Cayenne callbacks and listeners. Callbacks can be mapped in the Modeler and can not have any references to the app outside the object. So for your case listeners can be a solution. They can be DI-managed and mapped in Guice.
In bootstrap, I would like to:
Load a list of objects from the database
Extract information from the list of objects
Manipulate the extracted information, creating a new list from the extracted information
Cache the new list
Access the new list at any point after bootstrap has finished running from a controller or service
Is there a plugin to help me do this?
It doesn't look like caching (i.e. temp value, ephemeral, that could be lost at any moment), it's precalculated value. Don't think cache plugin will help.
Basically you need a place to keep this value. It could be anything actually, a static variable from a basic POJO class for example. But if we're talking about Grails I suggest to make a special Service, that will store value, have a method to get it, and probably a method to make initial calculations. Service is a singleton, shared between different artifacts, it will be easy to extend with new logic, refactor and support this code in future. And easier to understand/remember, in contrast to some magical value coming from a cache.
Like:
class SuperValueService {
def value
void refresh() {
value = ...
}
}
Init in bootstrap:
class Bootstrap {
def superValueService
def init { ->
superValueService.refresh()
}
}
and use from controller:
class MyController {
def superValueService
def action() {
render models: [superValue: superValueService.value]
}
}
I'm using compile 'com.google.guava:guava:18.0-rc2' see wiki, which provides also auto-eviction.
I want to use some caching from the Guava-library in my Grails app. Is a service class with a non-static field and some getter the best place to put this cache into? Or should it be static or declared somewhere else?
Basic Example:
class TestService {
def getCachedValue(Test test) {
return testCache.get(test)
}
def testCache = new CacheBuilder()
.maximumSize(2000)
.weakKeys()
.weakValues()
.expireAfterWrite(30, TimeUnit.SECONDS)
.build(
new CacheLoader<Test, Date>() {
...
Using a service is the best idea for this. However, making it static is a bit unnecessary since by default services are singletons.
The fact a service is a singleton, and is exposed to not only your controllers but other artifacts within your Grails application make it a perfect fit for accessing an object cache. A single point of access.
I am using the ApplicationContext passed in by Grails to the mapping closure in domain objects to get to the configuration information, like so
static mapping = { applicationContext ->
datasources(applicationContext.getBean("grailsApplication").config.dbList)
}
where dbList is my own variable in Config.groovy.
Is this the best way to go in Grails 2.0? Is it safe to assume this will be passed in? It works, just relies on the undocumented variable, thought I should ask.
you can use grails.util.Holders
Holders.config.dbList
There's something I just don't get about guice: According to what I've read so far, I'm supposed to use the Injector only in my bootstrapping class (in a standalone application this would typically be in the main() method), like in the example below (taken from the guice documentation):
public static void main(String[] args) {
/*
* Guice.createInjector() takes your Modules, and returns a new Injector
* instance. Most applications will call this method exactly once, in their
* main() method.
*/
Injector injector = Guice.createInjector(new BillingModule());
/*
* Now that we've got the injector, we can build objects.
*/
RealBillingService billingService = injector.getInstance(RealBillingService.class);
...
}
But what if not all Objects I ever need can be created during startup? Maybe I want to respond to some user interaction when the application is running? Don't I have to keep my injector around somewhere (e.g. as a static variable) and then call injector.getInstance(SomeInterface.class) when I need to create a new object?
Of course spreading calls to Injector.getInstance() all over the place seems not to be desirable.
What am I getting wrong here?
Yes, you basically only should use the Injector to create get the instance for the root-object. The rest of the application shouldn't touch the Guice-Container. As you've noticed, you still need to create some objects when required. There are different approaches for doing that, each suitable for different needs.
Inject a Provider
Provider is a interface from Guice. It allows you to request a new instance of a object. That object will be created using Guice. For example.
class MyService{
private Provider<Transaction> transactionProvider;
public MainGui(Provider<Transaction> transactionProvider){
this.transactionProvider = transactionProvider;
}
public void actionStarted(){
Transaction transaction = transactionProvider.get();
}
Build a Factory
Often you need some kind of factory. This factory uses some injected services and some parameters and creates a new object for you. Then you use this factory for new instances. Then you inject that factory and use it. There also help for this with the AssistedInject-extension
I think with these two possibilities you rarely need to use the Guice-Injector itself. However sometimes is still appropriate to use the injector itself. Then you can inject the Injector to a component.
To extend on the answer Gamlor posted, you need to also differentiate between the object types you are using.
For services, injection is the correct solution, however, don't try to always make data objects (which are generally the leafs in your object graph) injectable. There may be situations where that is the correct solution, but injecting a Provider<List> is probably not a good idea. A colleague of mine ended up do that, it made the code base very confusing after a while. We just finished cleaning it all out and the Guice modules are much more specific now.
In the abstract, I think the general idea is that if responding to user events is part of the capabilities of your application, then, well...
BillingService billingService = injector.getInstance(BillingService.class);
billingService.respondToUserEvent( event );
I guess that might be a little abstract, but the basic idea is that you get from Guice your top-level application class. Judging from your question, I guess that maybe BillingService isn't your top-level class?