Spring injection in xml using add method - spring

I would like to inject one bean into another using an addProperty method. For example, if I have bean A and bean B and bean B has a method addA() but not setter method, how do I inject bean A into B without resorting to annotations.

You could do it like this:
<bean id="a" class="my.A" />
<bean id="b" class="my.B" />
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="b" />
<property name="targetMethod" value="addA" />
<property name="arguments" ref="a" />
</bean>
Of course, this approach doesn't scale well if you've got a lot of bean-wiring to do. If you own the code, you should use Spring annotations and auto-wiring, or define setters and use the 'property' Spring XML tags.

Related

Injecting multiple property values to multiple beans

I have handler bean with a url property which needs different value for different class injections .How can I do this without creating multiple beans
<bean id="handler" class="com.Handler">
<property name="url" value="/"/>
</bean>
<bean id="a" class="com.A">
<property name="handler" ref="handler"> for this I need url to be /aaa
</bean>
<bean id="b" class="com.B">
<property name="handler" ref="handler"> for this I need url to be /bbb
</bean>
.....
I do not want to create multiple handler beans

Inject object attribute to spring bean

I want to know how to inject attribute of an Object to another Spring bean in Spring XML configurations? I have declared a bean in configuration file and I want to inject attribute of that bean into another bean.
Update:
Here is the configurations I tried in the spring.xml file.
<bean id="cFactoryBean" class="org.springframework.data.cassandra.config.CassandraClusterFactoryBean>
<property name="contactPoints" value="${cassandra.contactpoints}" />
<property name="port" value="${cassandra.port}" />
</bean>
<bean id="sFactoryBean" class="org.springframework.data.cassandra.config.CassandraSessionFactoryBean>
<property name="cluster" value="${cFactoryBean.object}" />
<property name="keyspaceName" value="${cassandra.keyspace}" />
<property name="converter" ref="cConverterBean" />
</bean>
I have created cFactoryBean bean and I want to inject object property of cFactoryBean to the 'cluster' property in the sFactoryBean.
In the following example the attribute connectionManager of the class Dao
refers to the spring bean dbConnectionManager.
<bean id="feedbackDao" class="com.foo.Dao"
<property name="connectionManager" ref="dbConnectionManager" />
</bean>
<bean id="dbConnectionManager" class="com.foo.dao.ConnectionManager" />

Spring factory-bean with property resolution

Is it possible to have property resolution on the factory-bean field of a Spring bean declaration?
Example:
<bean factory-bean="$APP{some.factory.bean}" factory-method="...">
Spring version: 3.2.4
Adding a PropertyPlaceholderConfigurer to your spring context should work:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:yourfile.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="false" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
</bean>
You can declare your propertyName in the file and then use it like:
<bean factory-bean="${propertyName}" factory-method="...">
Just encountered the same issue (using Spring 4.2.0). It seems that property resolution for factory beans does not work despite what they say in SPR-12638. I've ended up using ProxyFactoryBean as a workaround.
The desired configuration, which does not work:
<!-- The bean to be created: factory type determined in runtime -->
<bean id="..." factory-bean="factory-${factory.type}" factory-method="..." />
<!-- Possible factories -->
<bean id="factory-A" class="..." />
<bean id="factory-B" class="..." />
<bean id="factory-C" class="..." />
The workaround that I've found:
<!-- The bean to be created: use factory proxy -->
<bean id="..." factory-bean="factory-proxy" factory-method="..." />
<!-- The factory proxy: real factory type determined in runtime -->
<bean id="factory-proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="factory-${factory-type}" />
</bean>
<!-- Possible factories -->
<bean id="factory-A" class="..." />
<bean id="factory-B" class="..." />
<bean id="factory-C" class="..." />
Enjoy :)

PayloadValidatingInterceptor - validate only concrete wsdl

I have one Spring WS servlet with two endpoints and two wsdl files. Requests/responses are being validated with PayloadValidatingInterceptor. Content of spring-ws-servlet.xml:
<context:component-scan base-package="cz.legend.mzv.spi.ws.ei.endpoints" />
<context:component-scan base-package="cz.legend.mzv.spi.ws.de.endpoints" />
<sws:annotation-driven />
<sws:static-wsdl id="entityImport" location="classpath:/wsdl/entityImport.wsdl" />
<sws:static-wsdl id="documentEvidence"
location="classpath:/wsdl/documentEvidence.wsdl" />
<oxm:jaxb2-marshaller id="jaxb2Marshaller"
contextPath="cz.legend.mzv.spi.ws.jaxb.generated" />
<bean id="endpointAdapter" class="org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter">
<constructor-arg ref="jaxb2Marshaller" />
</bean>
<sws:interceptors>
<bean
class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
<property name="schema" value="classpath:/xsd/vums_spi_de.xsd" />
<property name="validateRequest" value="true" />
<property name="validateResponse" value="true" />
</bean>
</sws:interceptors>
Interceptor is applied on both services. I need the interceptor to be applied only on service described by documentEvidence.wsdl. One option is to make two separate spring servlets. But I want to use only one servlet.
Solution:
Alternatively, you can use or
elements to specify for which payload root name or SOAP action the
interceptor should apply:
<sws:interceptors>
<bean class="samples.MyGlobalInterceptor"/>
<sws:payloadRoot namespaceUri="http://www.example.com">
<bean class="samples.MyPayloadRootInterceptor"/>
</sws:payloadRoot>
<sws:soapAction value="http://www.example.com/SoapAction">
<bean class="samples.MySoapActionInterceptor1"/>
<ref bean="mySoapActionInterceptor2"/>
</sws:soapAction>
</sws:interceptors>

Accessing data from session-scoped beans in JSP files

I'm trying to get started with session-scoped beans in Spring Web MVC 3. I put this line in my dispatcher configuration:
<bean id="userInfo" class="net.sandbox.sessionbeans.UserInfo" scope="session" />
Here is net.sandbox.sessionbeans.UserInfo:
package net.sandbox.sessionbeans;
public class UserInfo {
public String username;
public UserInfo() {
this.username = "Unregistered User";
}
}
How can I access session-scoped beans inside the JSP files that represent the View part of my application? I tried this...
<p align="right">${userInfo.username}</p>
... but that didn't give me the expected result, i.e.
<p align="right">Unregistered User</p>
Instead I just get
<p align="right"></p>
What am I doing wrong?
You can do it as you show in your question. The problem is probably in your configuration. Look if you expose your beans in the view, like this:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
<property name="exposeContextBeansAsAttributes" value="true" />
</bean>
You can expose individual beans to JSTL with Spring.
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="exposedContextBeanNames">
<list>
<value>someBean</value>
<value>someOtherBean</value>
</list>
</property>
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
This answer is partially based on some advice that was posted in the question's comments but was later deleted by the poster. I added this to every JSP page that needs to use the bean:
<jsp:useBean id="userInfo" scope="session" class="net.sandbox.sessionbeans.UserInfo" />
I then found this article detailing how you can use beans in a JSP page.
You need to make sure that you have
<aop:scoped-proxy/>
enabled in your xml configuration.
For Example:
<!-- an HTTP Session-scoped bean exposed as a proxy -->
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<!-- this next element effects the proxying of the surrounding bean -->
<aop:scoped-proxy/>
</bean>
You can read more about it in Spring reference guide, "Bean scopes" chapter.
Elaborating on #sinuhepop suggestion below.
An easy way to do this is to configure spring so that it exposes the spring bean ids as varibales to JSTL this can be done by setting the exposeContextBeansAsAttributes property to true
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="exposeContextBeansAsAttributes" value="true"/>
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
If you have a bean configured like so
#Component
#Scope(proxyMode=ScopedProxyMode.TARGET_CLASS,value=WebApplicationContext.SCOPE_SESSION)
public class SomeBean {
}
Then in the JSP page you can access the bean using the name ${someBean.someProp} because that is the name that Spring will auto assign to the SomeBean unless the bean is defined with a name such as #Component("someName") then the JSTL would be ${someName.someProp}
An update to this answer for those, who want to use Spring 5 Java configuration. Addding this to your WebMvcConfigurer
#Override
public void configureViewResolvers(ViewResolverRegistry registry){
InternalResourceViewResolver resolver = new InternalResourceViewResolver("/WEB-INF/view", ".jsp");
resolver.setExposeContextBeansAsAttributes(true);
registry.viewResolver(resolver);
}
is equivalent to this XML config mentioned by others:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
<property name="exposeContextBeansAsAttributes" value="true" />
</bean>
Note, that the "convenient" fluent API of the registry (registry.jsp(). ...) does not offer you the possibility to configure the exposeContextBean.... properties.
If possible, you should consider using exposeContextBeanNames. Use constants as much as possible for your bean names, though, to avoid duplicating string literals in your code. So maybe define a String Array within some class, which collects all theses constants and exposes them to your view resolver.

Resources