Best Pratices and Tweaks in Spring FrameworkFrom WikiJava
Ganesh Gowtham's Website
SummaryIn this article we will see some best of practices that we can incorporate using theSpring Framework for the folks who had just crossed beginner level (or) who are very enthusiastic to know more @ younger age What is Spring Framework1 Main Modules of Spring Framework2 Design patterns used in Spring Framework3 Usage of JNDI,JdbcTemplate,DelegatingActionProxy,Junit,PropertyPlaceholderConfigurer
Usage of Junits using AbstractTransactionalSpringContextTestsFor Junit which used AbstractTransactionalSpringContextTests api , Please refer my another article
AbstractTransactionalSpringContextTests Example Usage of PropertyPlaceholderConfigurerIn Spring, you can use PropertyPlaceholderConfigurer class to externalize the deployment details into a properties file, and access from bean configuration file via a special format – ${variable}.
Instead of hard coding value in xml , if we use PropertyPlaceholderConfigurer , we have facility to import the content of properties file later if need we change the properties file not need for changing the xml file , in xml we can refer the key with EL Below in spring-persistence.xml You can able to see the usage .
in db-config.properties i had line jdbc.driverClassName=org.hsqldb.jdbcDriver
in spring-persistence.xml , i refered as ${jdbc.driverClassName} .
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>classpath:db-config.properties</value> </property> </bean> Usage of DelegatingActionProxy
TODO struts-config.xml <struts-config> ... <action-mappings> <action path="/searchWikiUser" type="org.springframework.web.struts.DelegatingActionProxy"> <forward name="success" path="/pages/displayWikiUsers.jsp" /> </action> ... </action-mappings> .... </struts-config> spring-presentation.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > <beans> <bean name="/searchWikiUser" class="com.jpratice.action.SearchWikiUsers"> <property name="wikiUserService" ref="wikiUserService" /> </bean> </beans> spring-persistence.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > <beans> <!-- data source --> <bean class="org.apache.commons.dbcp.BasicDataSource" id="wikiDataSource" 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}" /> <property name="defaultAutoCommit" value="true" /> <property name="maxActive" value="30" /> </bean> <!-- Property file configuration --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>db-config.properties</value> </property> </bean> <!-- jdbctemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="wikiDataSource" /> </bean> <!-- dao --> <bean id="wikiUserDao" class="com.jpratice.dao.WikiUserDao"> <property name="jdbcTemplate" ref="jdbcTemplate" /> </bean> </beans> db-config.properties jdbc.driverClassName=org.hsqldb.jdbcDriver
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > <beans> <bean id="wikiUserService" class="com.jpratice.service.WikiUserService"> <property name="wikiUserDao" ref="wikiUserDao" /> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > <beans> <bean class="com.jpratice.bean.EnvBean" id="EnvBean"> <property name="deployedEnv"> <bean class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/deployedEnv" /> </bean> </property> <property name="deployedAppVersion"> <bean class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/deployedAppVersion" /> </bean> </property> </bean> </beans> </property> spring.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > <beans> <import resource="/spring_persistence.xml" /> <import resource="/spring_service.xml" /> <import resource="/spring_presentation.xml" /> <import resource="/spring_jndi.xml" /> </beans> Its really Nice to have finely grained Spring XML's like Spring-Presentation.xml --> where it has details about actions, service injection Spring-Service.xml --> Tx management , service and dao injections Spring-security.xml( optional if we have some acegi security configuartions ) Spring-persistence.xml ( Beans of DataSource,Hibernate's session factory,JdbcTemplate...) Spring.xml ( which wont do much rather than importing all above files) In this manner it would be really easy for user to declare beans in respective xml's Importing the different Spring files for clean separation based on different layers5 Importing the properties file present in jar which is kept @ classpathIn Spring, you can use PropertyPlaceholderConfigurer class to externalize the deployment details into a properties file, and access from bean configuration file via a special format – ${variable}.
Instead of hard coding value in xml , if we use PropertyPlaceholderConfigurer , we have facility to import the content of properties file later if need we change the properties file not need for changing the xml file , in xml we can refer the key with EL Below in spring-persistence.xml You can able to see the usage .
in db-config.properties i had line jdbc.driverClassName=org.hsqldb.jdbcDriver
in spring-persistence.xml , i refered as ${jdbc.driverClassName} .
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>classpath:db-config.properties</value> </property> </bean> Time taken by each method executionlong startTime = System.currentTimeMillis(); //... line 1 //... line 2 long endTime = System.currentTimeMillis(); System.out.println("Time Taken by method to execute the lines : "+(endTime-startTime)); Below code which uses the spring frmk to track the time taken by each method execution import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import junit.framework.Assert; import org.springframework.util.StopWatch; /** * * @author Ganesh Gowtham * http://sites.google.com/site/ganeshgowtham */ public class WatchUtils { private static StopWatch watch = null; private static final String ASSERT_MSG = "StopWatch should be instantiated with resetAllTasks()"; /** * creates the Task with name specified * @param taskName */ public static void startTask(String taskName) { Assert.assertNotNull(ASSERT_MSG,watch); watch.start(taskName); } /** * End's the current task * */ public static void endTask() { Assert.assertNotNull(ASSERT_MSG,watch); watch.stop(); } /** * prints the summary of Time consumed in formatted manner * @return */ public static String getTaskSummary() { Assert.assertNotNull(ASSERT_MSG,watch); return watch.prettyPrint(); } /* * reset's all Old task and create the fresh StopWatch */ public static void resetAllTasks() { watch = new StopWatch("-- DEBUGGING --"); } public static void main(String[] args) { WatchUtils.resetAllTasks(); List<Integer> list = new ArrayList<Integer>(); Map<Integer, Integer> map = new HashMap<Integer, Integer>(); WatchUtils.startTask("time taken for adding objects in Arraylist"); for(int i=0;i<9000;i++){ list.add(i); } WatchUtils.endTask(); WatchUtils.startTask("time taken for adding objects in HashMap"); for(int i=0;i<9000;i++){ map.put(i,i); } WatchUtils.endTask(); System.out.println(WatchUtils.getTaskSummary()); } } Ouput for the above Code . StopWatch '-- DEBUGGING --': running time (millis) = 29 ----------------------------------------- ms % Task name ----------------------------------------- 00005 017% time taken for adding objects in Arraylist 00024 083% time taken for adding objects in HashMap In Above metrics we can see that 83% of time is used by adding elements in Hashmap itself and only 17% is consumed by adding elements in ArrayList. Practical Usage will be like placing WatchUtils.startTask(" ... ") and WatchUtils.endTask(); before and after the calling methods which executes the logic which you suspect will take some time .
ReferencesSpring Framework |
