Autowiring custom Spring component in Grails

I have a custom Spring that comes in a jar, which is then installed as a dependency on my Grails application. I load the app-context for the bean using the importBeans statement in resoueces.groovy, for example

beans = { importBeans('classpath:app-context-my-component.xml') } 

app-context-my-component.xml has some bean definitions and the following lines

 <context:annotation-config /> <context:property-placeholder location="classpath:my-component.properties" /> 

The component I'm trying to use with Grails is annotated with @Component("myComponent") .

Grails loads the external context of the application. I know this because at the beginning I did not have a .properties file on the classpath, and we are not a return mechanism for a missing property in @Value declarations.

In the Grails controller, the component is used as

 class MyController { def myComponent def someaction() { myComponent.doSomething() } } 

As a result, a NullPointerException is thrown, that is, the automatic installation of the component does not work after all . I tried using @Autowired in the controller, but it caused such weird problems that I thought it might not be the road I want to take.

The version of Grails used is 2.3.6. The Spring component is also configured to use Spring version 3.2.7 to avoid incompatibility.

UPDATE

Now, again in my hands for this problem, I set up Spring log to find out what is happening. Well, there is a lot of logging that causes Spring context to load, but here's what I managed to grep from across the batch

 INFO xml.XmlBeanDefinitionReader Loading XML bean definitions from class path resource [app-context-my-component.xml] INFO support.PropertySourcesPlaceholderConfigurer Loading properties file from class path resource [my-component.properties] DEBUG framework.CglibAopProxy Unable to apply any optimisations to advised method: public myapp.external.MyComponent myapp.MyService.getMyComponentClient() DEBUG framework.CglibAopProxy Unable to apply any optimisations to advised method: public myapp.external.MyComponent myapp.MyService.getMyComponentClient() DEBUG framework.CglibAopProxy Unable to apply any optimisations to advised method: public myapp.external.MyComponent myapp.MyService.getMyComponentClient() DEBUG framework.CglibAopProxy Unable to apply any optimisations to advised method: public void myapp.MyService.setMyComponentClient(myapp.external.MyComponent) DEBUG framework.CglibAopProxy Unable to apply any optimisations to advised method: public void myapp.MyService.setMyComponentClient(myapp.external.MyComponent) DEBUG framework.CglibAopProxy Unable to apply any optimisations to advised method: public void myapp.MyService.setMyComponentClient(myapp.external.MyComponent) 

I changed the log namespaces, but the myapp.external namespace refers to the external jar package, and the myapp namespace refers to the Grails application namespace. I changed the use, so the external component is used from the Service, and not directly from the controller, but this detail did not change the behavior.

In my understanding, loading the Spring context went well.

UPDATE 2

Based on @ th3morg's answer , I had the idea to try only using the XML configuration, skipping all @Component and such annotations from the bean. And it worked! Grails has now been able to import beans, which no longer leads to the use of NPE.

Although this solves my problem, at least in part. I'm still interested in a solution where Spring annotations can be used.

+5
source share
1 answer

You must ensure that component scanning is installed in your bank. Check out the “Using Spring Namespaces” section here http://grails.org/doc/latest/guide/spring.html#theBeanBuilderDSLExplained . You can also use resource.xml and add component scanning to this file if you cannot change your jar.

Alternatively, you can also connect beans one by one, although this is cumbersome and tedious:

 beans = { myComponent(com.my.MyComponent){ someOtherService = ref('someOtherService') //if there are other beans to wire by name propertyOne = "x" propertyTwo = 2 } } 
+6
source

Source: https://habr.com/ru/post/1204697/


All Articles