I am using ehcache in my project so when server start data of few table will be loaded into the cache ..in my application i am using Spring,Hibernate,JSF
I m using this configurationin applicationCOntext.xml file
<bean id="cacheManager" class="com.ccc.service.cache.CacheManager" init-method="init">
<property name="delay" value="${timer.delay}" />
</bean>
<bean id="companyCache" class="com.ccc.service.cache.clients.ValidCacheClient"/>
<context:component-scan base-package="com.ccc.spring" />
<context:annotation-config />
<context:spring-configured />
In Jsf Managed Bean i am creating Object of Service class like this
#ManagedProperty(value = "#{GlobalDataService}")
static GlobalDataService globalDataService;
But in ValidCacheClient.java how to create object of Service class? ValidCacheClient.java is not a manged class so how to create the Object of Service class?
You have two options:
Inject the necessary beans to be known from JSF as ServletContext attributes, so these beans will be treat by JSF as application scoped attributes. You can do this using Spring ServletContextAttributeExporter:
<bean class="org.springframework.web.context.support.ServletContextAttributeExporter">
<property name="attributes">
<map>
<entry key="globalDataService" value-ref="GlobalDataService" />
</map>
</property>
</bean>
Then you can inject it without problems in JSF:
#ManagedProperty(value = "#{globalDataService}")
GlobalDataService globalDataService; //no need to be static
Let Spring container manage the lyfecycle of JSF managed beans. With this approach, you may inject the springs beans using #Autowired. This is covered in Spring 3 + JSF 2 tutorials. Still, note that if you do this, you will lose access to JSF 2 view scope (crucial when working with ajax requests in the same view) because Spring still cannot support it. But this can be solved by creating a custom implementation for view scope, like Cagatay's
IMO I would use the latter approach rather than the former.
More info:
Set attributes of ServletContext in Spring 3.2 MVC configuration
Mkyong tutorial to integrate Spring 3 and JSF 2.0
Bean properties are shared across different sessions
Integration jsf, spring, hibernate. How to inject Spring beans into JSF managed beans?
Related
I'm planning to build a library using spring and use it as an mvn dependency. The library would be used as an api in several projects. The api does only database operations. Can the included dependency get the datasource/jdbcTemplate of the project it is included in as an Autowired spring bean?
the datasource/jdbctemplate that we use in the spring application context is like following
<bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg index="0" type="javax.sql.DataSource" ref="dataSource" />
</bean>
Yes. As long as there is a been with the name datasource and class javax.sql.DataSource. It needs to be available either through configuration, XML wiring or component scanning.
If creating a new library API it would be good to document what the user needs to make available for wiring.
My project framework is designed in such a way that I don't have access to Springs ApplicationContext. However, I would like to inject beans based on a system property. If the property is set to true, then inject all the beans, else inject none. Is this a possibility. Something like the below. BTW, Spring version is 3.0
<!-- all beans -->
<bean></bean>
<bean></bean>
<bean></bean>
<bean class ="org.springframework...PropertyPlaceHolderConfigurer>
<property name = "properties"
<value>
OBJECT_INSTANCE_ID =0
</value>
</property>
<bean>
In short the property is read using PropertyPlaceHolderConfigurer. All other beans should load based on value OBJECT_INSTANCE_ID. The property is defined in a property file located at /etc/../system.property
You can use Spring profiles to achieve this functionality:
<beans profile="dev">
<bean id="devConfig" class="<yourClassName>" />
</beans>
In the above example, the devConfig bean will be constructed only if dev profile is activated. You can activate a profile as follows:
Using annotations:
#ActiveProfiles("dev")
Using system property:
-Dspring.profiles.active=dev
If you would go for modern approaches like Java configs and Spring Boot, you can use #ConditionalOnProperty annotation that Spring Boot introduced as one of the conditional injections.
In Spring, beans can be configured to be lazily initialized. Spring Batch jobs are also (Spring-managed) beans. That is, when I configure something like
<sb:job id="dummyJob" job-repository="jobRepository">
<sb:step id="dummyStep">
<sb:tasklet ref="dummyTasklet" />
</sb:step>
</sb:job>
I actually configure a new (Job-typed) bean inside the Spring container.
My issue is I really want my Job beans to be lazily initialized. As they are regular Spring-managed beans, I'd expect I can instruct the Spring context to make them lazy. This is because I have a large number of beans and there are many cases in which, during one execution of my Spring-based application, I only run one job.
But there's no lazy-init property I can set on my <sb:job... \> configuration. Is there any way I can force lazy initialization? If I configure my <beans\> root with default-lazy-init="true", will this also apply to the Job beans?
You have two options here:
Configure your job manually. This would allow you to use the regular lazy-init attributes Spring exposes.
Use the JobScope now available in Spring Batch 3. Spring Batch 3 will be available soon, but the JobScope was available in the last milestone.
Just to elaborate on Michael Minella's answer.
I had a similar requirement to lazy initialize the job repository.
I am working with Spring Batch 2.1.9.
The following is working for me.
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
lazy-init="true">
<property name="dataSource" ref="jobDataSource"/>
<property name="transactionManager" ref="jobTransactionManager"/>
</bean>
Note one pitfall I had run into: do not set the databaseType i.e. avoid the following:
<property name="databaseType" value="SQLSERVER"/>
This is bad because it disable the auto-discovery of the database type and breaked my JUnits that works on H2.
I'm currently learning EclipseLink and Spring 3.0 MVC:
I wrote a simple standalone application using EclipseLink : it uses a META-INF/persistence.xml file and it reads and writes data from a mysql database.
I also wrote a simple 'HelloWorld' application using Spring3 MVC under apache tomcat. It is based on the following tutorial: http://www.mkyong.com/spring-mvc/spring-3-rest-hello-world-example
now, how should I link both technologies ? As far as I understand from http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch14s06.html I need to create a LocalContainerEntityManagerFactoryBean:
<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="someDataSource"/>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
but what is "someDataSource" ? should I use another library like http://commons.apache.org/dbcp/ ? then what should I do with eclipselink ?
And once the JPA will be configured, how should I access it from my spring Controller ?
Thank you
someDataSource would just be another bean, for example:
<bean id="someDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
Here I'm also using a property replacement for the properties, this is designated by the following bean:
<context:property-placeholder location="classpath:properties/runtime.properties" />
Since context is under a different xml namespace add:
xmlns:context="http://www.springframework.org/schema/context"
to your XML namespaces, and
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
to your schemaLocation string within the bean xml document.
classpath:properties/runtime.properties
This property file would be found at the following location in a standard Maven setup:
src/main/resources/properties/runtime.properties
Within this runtime.properties file you'd need to define values for each of the properties that have placeholders (i.e. jdbc.driverClassName, jdbc.url, etc.). An example of this would be:
jdbc.driverClassName=com.mysql.jdbc.Driver
If you're using MySQL for your database.
Generally speaking, you might want a service layer between your controller and repository (DAO). The reason being is controller should concentrate only on handling requests, and responding. Any business logic should be done in a different layer, through business objects, etc. Service layer acts as an intermediary between web layer, and repository layer. This not only separates concerns, but also makes things infinitely more unit testable, a huge part of any Spring application (at least it should be!).
As to how to wire things up, try inserting this bean into your Context as well:
<context:component-scan base-package="xx.yy..." />
Where xx and yy are your package names, this will tell Spring to scan your packages for "components" or #Controller objects, #Service, and #Repository (there are a few other ones but those are the main things to know about). With this information provided to Spring, you can #Autowire beans (dependency inject) into other beans.
For example:
#Service
public class SomeServiceImpl implements SomeService
{
private SomeRepository someRepository;
#Autowired
public void setSomeRepository(SomeRepository someRepository)
{
this.someRepository = someRepository;
}
...
}
This will inject the repository into the service allowing you to access that repositories methods.
Another design tip, always program for interfaces in Spring. This is especially true when it comes to repositories due to the fact that early in development, you might want to implement a Hibernate repository, but down the line DBAs might scoff at that, and require a JDBC repository using straight SQL. This way, you just need to implement the Repository using a JDBC approach rather than Hibernate, inject the JDBC repository instead of Hibernate, and you're done.
Hope this gets you started!
I'm adding some features to an old EJB 2 application using Spring. The Spring application context used by the EJBs is a parent context of the web application as described here.
I'm trying to use a session scoped bean from within the EJBs. The bean in question is initialized from the EJB application context.
However, I get this error when trying to access the bean:
Caused by: java.lang.IllegalStateException: No Scope registered for scope 'session'
From what I've read, this is because the parentContextKey is not an instance of WebApplicationContext. Does anyone have an ideas of how I could get this working?
You may try to register the scope manually:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="session">
<bean class="org.springframework.web.context.request.SessionScope"/>
</entry>
</map>
</property>
</bean>
I guess it should work, because SessionScope itself depends only on the thread-bound request context exposed by the RequestContextListener and doesn't depend on the application context.
You can only use session-scoped Spring beans from within a Spring WebApplicationContext. There's no getting around this - no WebApplicationContext, no session-scoping.
Perhaps if you explained what you're trying to achieve, we could help further. Are you perhaps conflating stateful session EJBs with servlet sessions? They're not the same thing.