Spring 4 / Groovy DSL - autowiring - java

How do I enable autowiring when using the Groovy DSL in Spring 4?
if my config.groovy file currently looks like this:
beans {
mongoClient(com.mongodb.MongoClient)
hello(org.abiri.HelloImpl) {
mongoClient = mongoClient
}
}
Previously in XML configuration, we could have done this:
<bean id="hello" class="org.abiri.HelloImpl" autowire="byType" />
And we could even enable that for the whole file:
<beans default-autowire="byType" />
What is the equivalent of those XML snippets in the new Groovy DSL, i.e what do I need to do in order for the mongoClient to be autowired to hello ?

You need to use
hello(org.abiri.HelloImpl) { bean ->
bean.autowire = "byType"
}
The configuration closure is passed a parameter that you can use to configure things that would be attributes on the bean element in an XML configuration. In addition to autowire this includes scope, initMethod and destroyMethod.

Related

Spring - #Value returns null

I have a properties file under /src/main/resources/ and I want to load data from it using Spring.
In my Spring-context.xml I have this :
<context:property-placeholder location="classpath:UserUtil.properties" />
and also have <context:component-scan base-package="com.myApp" />
and in my class I load it like :
#Value("${injectMeThis}")
private String injectMeThis;
but the value is always null
EDIT:
to check if the value, I use this :
System.out.println(new myClass().getInjectMeThis());
System.out.println(new myClass().getInjectMeThis());
Spring will only parse #Value annotations on beans it knows. The code you use creates an instance of the class outside the scope of Spring and as such Spring will do nothing with it.
Assuming you have setup your application context correctly a #Value cannot be null as that will stop the correct startup of your application.
Your XML file contains a <context:component-scan /> assuming myClass is part of that package the easiest solution is to add #Component to myClass and then retrieve the instance from the context instead of creating a new instance.
In your class, add class level annotation #PropertySource("UserUtil.properties"). This should solve the problem.

Spring XML and java configuration together

I have a project with XML based spring configuration and want to define some new beans but in java class based configuration.
How to implement this so that i can also refer beans of java configuration in my XML config file.
You can import your xml config into java configuration, like so:
#Configuration
#ImportResource("classpath:pl/rav/springtest/resources/app.xml")
public class AppConfig {
#Bean(name="myMessageService")
MessageService mockMessageService() {
return new MessageServiceImpl();
}
}
When you want to refer from xml to the bean you just point to its name:
<property name="msgSrv">
<ref bean="myMessageService"/>
</property>
Then use ApplicationContext based on your java configuration.
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
As you started with xml config, you may be interested in other way around (importing java config into xml config) which I think was explained here

Syntax for specifying spring xml files in ClassPathXmlApplicationContext

I am trying to find out the syntax for specifying the spring's XML file in the constructor of ClassPathXmlApplicationContext. By syntax I don't mean the method signature but the actual string
For example the following three work.
ApplicationContext context = new ClassPathXmlApplicationContext("com/anshbansal/alarm/alarm.xml");
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:alarm.xml");
ApplicationContext context = new ClassPathXmlApplicationContext("alarm.xml");
I have googled and tried to go through the Spring 3.1.0 source code also. But I got stuck after doResolvePlaceholders method in org.springframework.core.env.AbstractPropertyResolver class of Spring. Specificaly I was not able to understand how placeholders are resolving to the path.
Can anyone share what is the syntax for the string to specify the xml file?
EDIT
I mean the syntax to specify path to spring xml file like in the constructor. I do not mean the syntax of the xml file itself.
Ok, I understand the question now :-). PropertyResolver is used only to put environment values (or property file values) into spring XML file, i.e.:
<context:property-placeholder location="file:///some/path/file.properties"/>
and then resolving them inside this spring xml, i.e.:
<bean id="mailInviteMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="${mail.from}"/>
<property name="subject" value="${mail.subject}"/>
</bean>
Putting spring XML in the classpath and naming in standard convention (i.e. beans.xml) is preferable. However, you may configure it putting a parameter to java invocation, i.e.
java -Dmy.parameter=/path/to/beans.xml ...
and then loading it manually:
Context context = new FileSystemXmlApplicationContext(System.getProperty("my.parameter"));

ways to inject a object of a class in spring controller?

I need to inject a object of a java class in spring controller through applicaionContext.xml. My controller will be ,
#Controller
public class SpringController{
private MyClass obj;
}
I know I can do it with #Autowired annotation.
Is this really good to create a object for a controller through applicaionContext.xml ? Also can I inject a object of a class in controller using the <property> tag inside a <bean> tag ?
Is this really possible ? or please forgive me if it is a stupid question.
I need to know the possible ways for how to inject a object of a class in Spring controller ?
You can of course use #Autowired annotation to autowire the relationships, which can reduce the need to define the properties and constructor arguments for the controller in your applicationContext.xml file. And also to add a dependency to a class, you don't need to modify the configuration files.
But it has some disadvantages too, like if you use #Autowired, there will not be any explicit documentation for the wiring details between Spring managed beans. And to know the relationships between the beans, you have to go through your managed beans. But, if you use configuration files to define the relationships, the relationship details can be found in one place.
You can inject an object of a class into your controller through your applicaionContext.xml as below:
Constructor based injection:
#Controller
public class SpringController{
private MyClass obj;
public SpringController(MyClass obj){
this.obj=obj;
}
}
<bean id="myClassImpl" class="x.y.z.MyClassImpl"></bean>
<bean id="springController" class="x.y.z.web.controllers.SpringController">
<constructor-arg ref="myClassImpl"></constructor-arg>
</bean>
Setter based injection:
#Controller
public class SpringController{
private MyClass obj;
public void setObj(MyClass obj){
this.obj=obj;
}
public MyClass getObj(){
return obj;
}
}
<bean id="myClassImpl" class="x.y.z.MyClassImpl"></bean>
<bean id="springController" class="x.y.z.web.controllers.SpringController">
<property name="obj" ref="myClassImpl"></property>
</bean>
If you want to inject an object in a controller and you particularly want to you use xml,then instead of component scanning of Controller you should create a bean of the controller class of singleton scope in the application context.
Your controller class need not be annotated with #Controller.
you then have to you extend some Controller also like AbstractCommandController, AbstractController, AbstractFormController, AbstractWizardFormController, BaseCommandController, CancellableFormController, MultiActionController SimpleFormController, UrlFilenameViewController
Now to inject a particular object you can use Either Constructor and Setter based injection.
or you can use Autowring by name or type to auto inject the object.
Make sure that you have also declared the bean of that object also in Application Context.
After a DispatcherServlet has received a request and has done its work to resolve locales, themes and suchlike, it then tries to resolve a Controller, using a HandlerMapping. When a Controller has been found to handle the request, the handleRequest method of the located Controller will be invoked; the located Controller is then responsible for handling the actual request and - if applicable - returning an appropriate ModelAndView.
Thats it.
Actually, injection with xml and annotation is same behind the scene. Xml is old fashion while annotations are newer.
Basically, there are 2 types of injection types.
byName
Autowiring by property name. Spring container looks at the properties
of the beans on which autowire attribute is set to byName in the XML
configuration file. It then tries to match and wire its properties
with the beans defined by the same names in the configuration file.
You can give explicit names to beans both with xml and annotation.
#Service("BeanName")
#Component("BeanName")
#Controller("BeanName")
<bean name="BeanName" class="someclass"></bean>
and inject beans by using #Qualifier annotation.
#Autowired
#Qualifier("BeanName")
and with xml
<bean id="MyBean2" class="MyBean2 class">
<property name="Property of MyBean2 which refers to injecting bean" ref="BeanName" />
</bean>
byType
Autowiring by property datatype. Spring container looks at the
properties of the beans on which autowire attribute is set to byType
in the XML configuration file. It then tries to match and wire a
property if its type matches with exactly one of the beans name in
configuration file. If more than one such beans exists, a fatal
exception is thrown.
Default auto wiring mode is byType, so spring will look for matching type in auto wiring. However, older versions of Spring has default behavior none on injection. If you want to inject byType using xml, you should tell spring contaioner explicitly.
For example MyBean2 has a reference to MyBean, by setting autowired attribute to byType it handles injection automatically.
<bean id="MyBean" class="MyBean class">
<property name="Property of MyBean2 which refers to injecting bean" ref="BeanName" />
</bean>
<bean id="MyBean2" class="MyBean2 class"
autowire="byType">
</bean>
It also depends on where the injection take place in your code. There are 2 types, setter getter injection and constructor injection.
Note : There is no difference in #Controller since they are already in spring context.
See also
Spring Beans Auto wiring
I ran into such problem. I was getting "Ambiguous mapping found". (I use xml configuration as well and i am injecting a bean into my controller)
Then looking at my console i realized that my controller was being instantiated twice.
In more detailed look i noticed that my annotation
#Controller(value = "aController")
(Note value = "aController")
was different from my xml configuration where i was instatiating the same controller with different bean id
<bean id="aControleRRRRR" class="package.ControllerClassName"
p:property-ref="beanToInject" />
(Note id="aControleRRRRR")
So in conclusion your #Controller name (value = "aController") needs to be exactly the same as the name you give in the XML configuration (id="aControleRRRRR"), so that Spring can manage to distinct that they refer to the same bean (instance)
Hope this helps

Spring #Value annotations don't work, returning null

I have the following class:
#Component
public class MyClass {
#Value("${main.url}") private String mainUrl;
the following XML context:
<context:annotation-config/>
<context:component-scan base-package="mypackage"/>
<context:property-placeholder file-encoding="UTF-8" location="classpath:/app.properties" ignore-unresolvable="true"/>
and prop file:
main.url=veryniceurl.com
Injection doesn't work, it is always null.
I read a lot of similar examples and I thought that everything is ok but it isn't. Can anyone tell me if I forgot about something? I'm working with Mule ESB.
#Value doesn't seem to work with Mule. Instead you need to wire it up through the Mule XML, where I assume you are loading your component as a Spring Bean:
<spring:bean id="MyClass" class="com.example.MyClass">
<spring:property name="mainUrl" value="${main.url}"/>
</spring:bean>
Give an id to your properties and use this syntax :
#Value("#{jetProperties['jetBean.name']}")
<!-- define the properties file to use -->
<util:properties id="jetProperties" location="classpath:/jet.properties" />
From http://chrislovecnm.com/2010/03/08/spring-3-java-based-configuration-with-value/
Did you add the context placeholder in the dispatcher-servlet.xml ? As per here, Spring #Value annotation in #Controller class not evaluating to value inside properties file they seem to have solved it by adding it there instead of the application context

Categories