getting a handle to the application context - spring

I am trying t learn various technologies - want to do some UI stuff using HTML5 with Jquery
In the UI I am making a call to a RESTFUL webservice ( Jersey ) which generates JSON output
In my webservice - I had stubbed the data that was supposed to come from the database ( mysql )
Now I want to learn Spring JDBC template ( and not use plain JDBC )
So my question is about using spring ( only spring jdbc and not spring mvc ) in a web application which hosts my RESTFUL webservice
I want to use spring jdbc template - so have written a spring xml file where I am creating the necessary configurations
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="....."
xsi:schemaLocation="....">
<bean id="examDAO" class="com.examscripts.mockexam.repository.ExamRepositoryImpl">
<property name="ds" ref="ds" />
</bean>
<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/mockexam" />
<property name="username" value="xxx" />
<property name="password" value="yyy" />
</bean>
To load these in I added the following in web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
on tomcat startup I can see that the file is loaded :
Loading XML bean definitions from class path resource ....
Now my question is in my service layer where I need to communciate with DAO layer ( jdbc ) - do have to create the actual bean using something like this :
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
// instantiate our spring dao object from the application context
ExamRepositoryImpl impl= (ExamRepositoryImpl)ctx.getBean("examDAO");
I am completely new to spring and googling seems to always show spring mvc web apps or standalone spring examples - my case is a web app minus spring mvc but using spring jdbc template
any pointers ?

Loading XML bean definitions from class path resource ....
You're on the right track. Spring is loading your XML file (when you deploy the app) and instantiating the beans that you declared. Crank up the logging for org.springframework to get more details.
Now my question is in my service layer where I need to communciate
with DAO layer ( jdbc ) - do have to create the actual bean using
something like this :
No, definitely not. The entire purpose of using a dependency injection framework like Spring is to avoid writing code like this.
Declare a setter in your service class that takes the DAO as an argument.
public void setExamDAO(ExamDao examDao) {
this.examDao = examDao;
}
Add a new XML bean definition for your service class in your XML file and create a new <property> that wires in the DAO:
<bean id="yourservice" class="com.foo.YourServiceClass">
<property name="examDao" ref="examDAO"/>
</bean>

Related

Xml configuration for JdbcChannelMessageStore in a Spring Boot project with Spring Data JPA

I am very new to Spring Integration and would like to use a queue channel which is backed by a JdbcChannelMessageStore.
As our project uses Spring Boot with Spring Data JPA, I would like to have an integration-context.xml configuration where the existing data base connection is reused. However I struggle to make it work.
Unfortunately I cannot find any example projects where JdbcChannelMessageStore is used. Could anyone provide some good example implementations for this?
Thanks a lot in advance.
P.S.: Here is my last integration-context.xml version:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<int:channel id="outgoingChannel">
<int:queue message-store="outgoingMessageChannelStore"/>
</int:channel>
<bean id="dp"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${spring.datasource.password}" />
<property name="username" value="${spring.datasource.username}" />
<property name="password" value="${spring.datasource.password}" />
</bean>
<bean id="outgoingMessageChannelStore" class="org.springframework.integration.jdbc.store.JdbcChannelMessageStore">
<property name="dataSource" ref="dp"/>
<property name="channelMessageStoreQueryProvider" ref="jdbcChannelMessageStoreQueryProvider"/>
<property name="region" value="TX_TIMEOUT"/>
<property name="usingIdCache" value="true"/>
</bean>
<bean id="jdbcChannelMessageStoreQueryProvider" class="org.springframework.integration.jdbc.store.channel.OracleChannelMessageStoreQueryProvider" />
<int:transaction-synchronization-factory id="jdbcChannelMessageStoreFactory">
<int:after-commit expression="#jdbcChannelMessageStore.removeFromIdCache(headers.id.toString())" />
<int:after-rollback expression="#jdbcChannelMessageStore.removeFromIdCache(headers.id.toString())" />
</int:transaction-synchronization-factory>
</beans>
With this I am getting the following Exception at startup:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
...
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
Well, since you say that you also use Spring Boot, you probably miss the fact that it auto-configure a DataSource bean for us. Having that dp bean in your config it just neglects that auto-configuration and tries to apply it everywhere you need DataSource, like that Hibernate auto-configuration.
What you really need is exactly opposite - you need to reuse an auto-configured DataSource for this Spring Integration config. Of course, if your JdbcChannelMessageStore is going to rely on the same data base as menitoned Spring Data JPA.
So, what you need is just remove that dp bean definition and use a dataSource name for the <property name="dataSource" in the outgoingMessageChannelStore bean definition.
Some remarks:
We don't need usingIdCache with Oracle and therefore no need in that jdbcChannelMessageStoreFactory to deal with the cache. And that even covered in JavaDocs:
* <p>If using the provided
* {#link org.springframework.integration.jdbc.store.channel.OracleChannelMessageStoreQueryProvider},
* don't set {#link #usingIdCache}
* to true, as the Oracle query will ignore locked rows.</p>
Try to configure Spring Integration with Java & Annotation Configuration (or even Java DSL). This way you won't be tied with a bean name (like that dataSource) and just will have a bean method argument injection for plain DataSource type and Spring container will inject for you an auto-configured bean.

Configure singleton CacheManager for multiple web applications with Spring Caching

I have multiple web applications deployed in Tomcat and service jar shared in TOMCAT_HOME/lib/ext. All of the application are using Spring, and in the service jar I have beans, annotated with Spring 3.1 Caching annotations . I am using Ehcache provider. And I want to have one single CacheManager used by all the web applications. If I define spring cache configurations at web application level, caching works, but separate cacheManager is created for every app/context. 'Shared' Cache Manager is causing problems, because if one the those applications gets undeployed, this shared cacheManager is shut down. So I want a single CacheManager , configured in my service jar, and used for all the calls to methods made from beans from the web apps. My current try is to define following confuguration in service.jar's applicationContext.xml:
<context:annotation-config/>
<context:component-scan base-package="com.mycompany.app" />
<context:component-scan base-package="com.mycompany.portal.service" />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehCacheManager"/>
<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="ehcache.xml" ></bean>
<cache:annotation-driven cache-manager="cacheManager"/>
I have defined parent application context via beanRefContext.xml:
<bean id="service.parent.context" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>applicationContext.xml</value>
</list>
</constructor-arg>
</bean>
And I am using this context as a parent context for all of my web apps with following contextParam in web app's web.xml:
<context-param>
<param-name>parentContextKey</param-name>
<param-value>service.parent.context</param-value>
</context-param>
The result is that this parentContext is loaded, but caching doesn't work at all
How can I solve this? Am I on the right way with the defining of the parentContext in the service.jar?
I don't think so. It looks like you are trying to have a single cache for multiple applications by "hacking" the root classloader.
If you need to share your cache across several applications, use a cache manager that supports that use case (i.e. that provides you a service you can reach from each application).

Unit Testing based on JNDI , ejb and spring

In my application I am injecting some of services based on EJB with use of Spring IOC through JndiObjectFactoryBean like below mentioned so during run the junit I am getting this exception "java.lang.IllegalArgumentException: This JNDI operation is not implemented by the JNDI provider."
Could some please let me know how I'll configure for Junit.
<bean id="xxxMenuItemService" class="xxxMenuItemServiceyyy">
<property name="xxxMenuItemDelegator" ref="xxxMenuItemDelegator" />
</bean>
<bean id="approveMenuItemServiceRemote"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"
value="ejb/XXXXXXXX" />
have a look at the SimpleNamingContextBuilder from org.springframework.mock as it provides a full context builder where you can bind mock or other objects for use by Spring's JNDI lookup.
One thing to do though is to make sure you build the SimpleNamingContextBuilder in the static #BeforeClass of JUnit 4. this means that it is all initialized and waiting before the Spring Application Context is started and you won't have any JNDI lookup failures.

How would I make this bean in JavaConfig, I dont want to use XML with Spring anymore

I am working on a project and I need to set the following bean and property but I dont want to do it in XML.. I want to do it in JavaCofig style.. Can someone please show me how I would do this in javaconfig stlye
<!-- Spring Configuration needed to avoid URI using dots to be truncated -->
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="useDefaultSuffixPattern" value="false" />
</bean>
Something like this should work:
#Bean public DefaultAnnotationHandlerMapping defaultAnnotationHandlerMapping(){
DefaultAnnotationHandlerMapping bean = new DefaultAnnotationHandlerMapping();
bean.setUseDefaultSuffixPattern(false);
return bean;
}
You can see my sample spring MVC app using code config here https://github.com/robhinds/spring-code-configuration-webapp/blob/master/src/main/java/com/tmm/web/configuration/WebMvcConfiguration.java

Spring does not autowire beans with JAX-WS webservice end points

I am trying to consume a JAX-WS webservice written by me. I always get nullPointerException for spring autowired annotated beans. However, everything works fine within serverSide over web, but accessing beans through JAX-WS webservice.
I have tried by extending SpringBeanAutowiringSupport, but still no luck. How can I do this.
regards, Rohit
I had no experience extending SpringBeanAutowiringSupport but had successfuly used this approach:
Annotate webService class such a way :
#Component("yourWebService")
#WebService(endpointInterface ="your.package.YourServicePort")
Create new spring-context xml for webService and define JAX-WS endpoint :
<jaxws:endpoint
id="yourServiceEndpoint"
implementor="#yourWebService"
address="${yourWebService.wsdl.url}"> //load url from properties file
</jaxws:endpoint>
I suppose you know how to use props in spring, but will explain just in case. You should also create yourWebService.properties file and define it in spring context to use this construction ${yourWebService.wsdl.url} :
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>yourWebService.properties</value>
</list>
</property>
Using this approach I had successfuly used JAX with Spring

Resources