I added a class in src/groovy that implements the DataBindingListener interface. My init/Application file registers the Spring bean in the doWithSpring method
#Override
Closure doWithSpring() {
def beans = {
applicationBindingListener(org.mkv.ApplicationBindingListener)
}
return beans
}
I confirmed the bean is registered. However it doesn't seem to be receiving any of the binding events.
I'm using grails 4.0.0
In my case, I edit config/spring/resources.groovy. It's the source.
beans = {
dataBindingListener org.mkv.ApplicationBindingListener
}
And, The code below is added as a test case method to ensure that the bean configured in the test code is used.
boolean loadExternalBeans() {
true
}
Related
In the example below, I successfully fall into the end point - mandatory() - although one of two mutually exclusive #Transactional annotations must throw an exception: whether Propagation.NEVER or Propagation.MANDATORY. But the code is executed successfully.
How could that be?!
A couple (not all) of my services are affected by that and I'd like to understand what is the cause.
class NewService {
static transactional = true
boolean process() {
return never()
}
#Transactional(propagation = Propagation.NEVER)
boolean never() {
return mandatory()
}
#Transactional(propagation = Propagation.MANDATORY)
boolean mandatory() {
// successfully breakpointed here o_O
return true
}
}
Grails 2.2.0
It looks like you are bypassing the bean proxy, as Burt Beckwith (Slide 23) called it "Unintentionally bypassing the bean proxy".
You need to get proxy and execute your method on that.
#Transactional(propagation = Propagation.NEVER)
boolean never() {
def myproxy= grailsApplication.mainContext.newService
return myproxy.mandatory()
}
#Transactional(propagation = Propagation.MANDATORY)
boolean mandatory() {
// successfully breakpointed here o_O
return true
}
Spring declarative transactions are AOP-based. And Spring AOP is proxy-based. This means that the transactional annotation is read and taken into account when a bean is called from another bean, through a proxy:
Bean A --> injected transactional proxy --> Bean B
In your case, you call another ethod of the same bean directly. The transactional proxy is thus not aware of this call, and thus can't enforce the presence of a transaction:
Bean A --> this
I am writing tests for my wicket-application and need to inject a Spring Bean into a page (done by annotation) to do this.
Consider following code:
protected void setUp() {
tester = new WicketTester();
scanService = new ScanService();
ApplicationContextMock appctx=new ApplicationContextMock();
appctx.putBean("pxGenericService", new PxGenericServiceImpl());
tester.getApplication().getComponentInstantiationListeners().add(new SpringComponentInjector(tester.getApplication(), appctx));
}
This actually seem to work (no nullpointer). The problem is: the bean got a resource (variable with #Resource annotation) and when I run the test on the page, this resource turns out to be null (nullpointer exception). How do I fix this problem?
You also have to add an instance of all dependencies your bean has to the mock application context. So add an instance of the class PxGenericServiceImpl uses to appctx.
I don't think that SpringComponentInjector supports #Resource. The only supported annotations are #SpringBean and #Inject. See AnnotProxyFieldValueFactory:
#Override
public boolean supportsField(final Field field)
{
return field.isAnnotationPresent(SpringBean.class) || field.isAnnotationPresent(Inject.class);
}
I am having a series of odd errors in testing and deployment. They seem to indicate that some of my beans are not loading into the context, despite them being defined in applicationContext.xml.
Is there any way to check during testing which beans have actually been loaded? Or to find a complete list of beans loaded at run time?
Thanks,
b
At startup, Spring logs at info level the names of all the beans being loaded by a context. Or in code, you can use getBeanDefinitionNames() to get all the bean names.
if there is more than one context say if you are using spring mvc you can use something more powerful like this.
public class SampleContextApplicationListener implements ApplicationListener<ApplicationContextEvent> {
private Map<String,ApplicationContext> contextMap = new Hashtable<String,ApplicationContext>();
#Override
public void onApplicationEvent(ApplicationContextEvent event) {
if( event instanceof ContextStartedEvent || event instanceof ContextRefreshedEvent){
this.getContextMap().put(event.getApplicationContext().getDisplayName(), event.getApplicationContext());
}
}
public Map<String,ApplicationContext> getContextMap() {
return contextMap;
}
}
You can then inject the listener where it is needed, and extract the map of contextens and then interogate it for all its bean, using the getBeanDefinitionNames()
#Autowired
private StatusTestsApplicationListener listener;
I have a domain class:
class Searcher {
String names
List<String> getExperiments() {
return names.split(',');
}
void setExperiments(List<String> list) {
names = list.join(',');
}
}
and a bean defined in the resource file
experiments(com.fxpal.querium.experiment.ExperimentHolder) {
otherProp = 'foo'
}
The experiments bean is semantically different from the experiments property of the Searcher class.
How do I prevent Spring from auto-wiring a specific property of a specific bean? Since the experiments property of the Searcher bean is derived, I don't want Spring to touch it at all.
Why not just name your bean experimentHolder? By default its going to auto wire by name.
I have a Grails application that needs to run a strategy that will likely be swapped out over time. I know Spring underlies Grails, so I was wondering if I had access to Spring's IoC container so that I could externalize the actual dependency in an xml file (note: I have never actually done this, but just know of it, so I may be missing something). My goal is to be able to do something like the following:
class SchemaUpdateService {
public int calculateSomething(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
IStrategy strat = (IStrategy) ctx.getBean("mystrat");
}
}
And then map the appropriate implementation in the beans.xml file. I assume this is supported in Grails. Does anyone have any documentation on how this would work? Do I really just need the Spring IoC library and it will just work? Thanks!
You define your beans in resources.xml or resources.groovy. The grails documentation is very clear about how to access the Spring application context.
You can access the application context from any Grails artefact using
ApplicationContext ctx = grailsApplication.mainContext
You can then use this to retrieve whichever beans you're interested in:
IStrategy strat = (IStrategy) ctx.getBean("mystrat")
In classes that don't have access to grailsApplication, you could use a helper such as the following to access the application context and the beans therein
class SpringUtils {
static getBean(String name) {
applicationContext.getBean(name)
}
static <T> T getBean(String name, Class<T> requiredType) {
applicationContext.getBean(name, requiredType)
}
static ApplicationContext getApplicationContext() {
ApplicationHolder.application.mainContext
}
}
However, this should only be necessary if you need to retrieve different implementations of the same bean at runtime. If the required bean is known at compile-time, just wire the beans together in resources.xml or resources.groovy
First of all, you want to define your strategy in your grails-app/conf/spring/resources.groovy:
beans = {
myStrat(com.yourcompany.StrategyImpl) {
someProperty = someValue
}
}
Then, you simply def the a property with the same name into your service:
class SomeGrailsService {
def myStrat
def someMethod() {
return myStrat.doSomething()
}
}
In any Grails artefact (such as services and domain classes), Grails will automatically give the myStrat property the correct value. But don't forget, in a unit test you'll have to give it a value manually as the auto-wiring does not happen in unit tests.
Outside of a Grails artefact, you can use something like:
def myStrat = ApplicationHolder.application.mainContext.myStrat
In Grails 2.0, Graeme et al are deprecating the use of the *Holder classes (such as ApplicationHolder and ConfigurationHolder), so I'm not quite sure what the Grails 2.0 approach would be...