You are on page 1of 9

Spring Best Practices


1. BeanFactory or ApplicationContext? : Prefer ApplicationContext over BeanFactory. BeanFactory is a simple
factory implementation to create and destroy spring beans. ApplicationContext is an advanced beanfactory which supports i18N text message resolution, resource loading and capable to posting events to listener beans. BeanFactory should be preferred when there is limitation on resources and size of the application. Singleton beans are loaded differently in BeanFactory and ApplicationContext. A bean factory lazily loads all beans, deferring bean creation until the getBean() method is called. An application context loads all singleton beans upon context startup. Your application won’t have to wait for them to be created if you are using ApplicationContext. Non singleton bean : By default all beans defined in spring are singleton. However you can ask spring to create unique instance of a particular bean setting "singleton" property of the bean to false. Such beans are called prototype. A new instance of a prototype bean will be created each time getBean() is invoked with the bean’s name. Protype beans incur hit on permance during creation. It should be avoided completely or designed carefully if it uses resources such as database or network connections. They are useful for factory to create new bean instances. Avoid spring interfaces: Avoid spring interfaces whenever possible. Spring is a great framework but the greatest advantage of spring is POJOs which makes it vendor independent. Avoid NameAware, BeanFactoryAware, and ApplicationContextAware interfaces. Example: To inialize or destroy a bean you can specify init-method and destroy-method in application context. It might be tempting to use Spring's InitializingBean and DisposableBean to avoid specifying these methods and spring takes care of it. Still you don't want to get locked with spring interface unless you want to make your business objects spring dependent. Inner Beans: Use Inner beans when you don't want a particular bean to available without its parents bean. Although it doesn't look pleasing to most eyes, it is still worth if you don't want beanfactory to use this bean. example: target for AOP proxy. Avoid using autowiring : Spring can autowire dependencies through introspection of the bean classes so that you do not have to explicitly specify the bean properties or constructor arguments. Bean properties can be autowired either by property names or matching types. Constructor arguments can be autowired by matching types. You can even specify the autodetect autowiring mode, which lets Spring choose an appropriate mechanism. Example : <bean id="orderService" class="com.lizjason.spring.OrderService" autowire="byName"/> The property names of the OrderService class are used to match a bean instance in the container. Autowiring can potentially save some typing and reduce clutter. However, you should not use it in real-world projects because it sacrifices the explicitness and maintainability of the configurations. It seems like a good idea to make the XML configuration file smaller, but this will actually increase the complexity down the road, especially when you are working on a large project where many beans are defined. Spring is bad is resolving ambiguities. Autowiring byType or byConstructor might result in ambuiguity exception. You should mix autowiring with explicit wiring and never rely completly on autowiring by default. Autowiring byName is more dangerous as bean names might be changed over time, leaving several beans unwired or wired to wrong beans. Use naming conventions : This is the same philosophy as for Java code. Using clear, descriptive, and consistent name conventions across the project is very helpful for developers to understand the XML configurations. For bean ID, for example, you can follow the Java class field name convention. The bean ID for an instance of OrderServiceDAO would be orderServiceDAO.For large projects, you can add the package name as the prefix of the bean ID. Import vs ApplicationContext : Like imports in Ant scripts, spring import elements assemble bean definitions. Example: <beans> <import resource="billingServices.xml"/> <import resource="shippingServices.xml"/> <bean id="orderService" class="com.lizjason.spring.OrderService"/> <beans>



4. 5.



Example: Instead of: <bean id="billingService" class="com.spring.xml"}.However. or value tags are used.lizjason. It can noticeably improve readability when many beans are defined in a configuration file.spring. instead of pre-assembling them in the XML configurations using imports.. since it moves property values and references from child elements into attributes.lizjason.OrderService"> <property name="companyName"><value>lizjason</value></property> <constructor-arg><ref bean="orderDAO"></constructor-arg> </bean> Can be rewritten in the shortcut form as: <bean id="orderService" class="com. 11. or via autowiring. hyphens. it is very rare to run into the XML IDREF constraint problem.lizjason. Use ids as bean identifiers : You can specify either an id or name as the bean identifier. but it can leverage the XML parser to validate the bean references. Prefer type over index for constructor argument matching : Spring allows you to use a zero-based index to solve the ambiguity problem when a constructor has more than one arguments of the same type.xml". underscores.spring. so that the container can do the dependency validation for you.. 9. The shortcut form not only saves you some typing. such as simple. "billingServices. colons. In reality. ApplicationContext orderServiceContext = new ClassPathXmlApplicationContext(serviceResources). It is useful when all of the properties (or certain categories of properties) of a bean must be set explicitly.lizjason. Using ids will not increase readability.lizjason. The issue with XML IDREF constraints is that the id must begin with a letter (or one of a few punctuation characters defined in the XML specification) followed by letters. or all. Using ApplicationContext also makes the XML configurations easy to manage. it is more flexible to configure them through the ApplicationContext. But the later approach sacrifice declarative feature of spring. "shippingServices. It is possible to enable the default dependency check for all of the beans.OrderService"> <property name="companyName"value="lizjason"/> <constructor-arg ref="orderDAO"/> </bean> There is no shortcut form for <ref local=". . Use shortcut forms : The shortcut form is less verbose.BillingService"> <constructor-arg type="java. but also makes the XML configuration files less cluttered. the container will ensure that properties that are not primitives or collections are set for the orderService bean.OrderService" dependency-check="objects"> <property name="companyName" value="jason"/> <constructor-arg ref="orderDAO"/> </bean> In this example.String" value="lizjason"/> <constructor-arg type="int" value="100"/> 10. Example: <bean id="orderService" class="com. digits.BillingService"> <constructor-arg index="0" value="lizjason"/> <constructor-arg index="1" value="100"/> </bean> It is better to use the type attribute like this: <bean id="billingService" class="com. objects. but this feature is rarely used because there can be beans with properties that don't need to be set. you can use names as the bean identifiers.spring.">.xml".lang.spring. Use dependency-check at the development phase : You can set the dependency-check attribute on a bean definition to a value other than the default none. You can pass an array of bean definitions to the ApplicationContext constructor as follows: String[] serviceResources = {"orderServices. or full stops. 8. If ids cannot be used due to XML IDREF constraints. <bean id="orderService" class="com.

springframework.jdbc. You should only use index when there is an ambiguity problem in the constructor arguments. 13. Although simply leaving property without setting any value defaults to null but the property might be set to some other default value within bean or if you are using auto wiring. Here 15. Seperate deployment details from application context : Try to seperate deployment details out of application context in other xml or properties file.springframework. . Autowiring byType or byConstructor might result in ambuiguity exception. Good for bean with one or two properties. Provides flexibility to create a valid object.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/myDataSource" /> </bean> Spring AOP or AspectJ AOP? : Spring provides proxy based aop implementation based on interceptor chains. Less code lines as setters could be avoided.jdbcDriver database. Ready to use if all arguement contructor is used. You should mix autowiring with explicit wiring and never rely completly on autowiring by default. 12.url}</value></property> <property name="driverClassName"><value>${database. It is also called dynamic AOP as changes in point cuts or joins doesn't require recompilation. factory. Setters are self explaining. 16. 14. but it is more error-prone and hard to read compared to using the type should contain the following entries: database.springframework. leaving several beans unwired or wired to wrong beans. Bean cannot be instantiated without being given all of its dependencies. Autowiring : Spring is bad is resolving ambiguities.jndi.driver}</value></property> <property name="username"><value>${database. Constructor vs Setter injection : The following table contains some points to consider in each method's favor.user}</value></property> <property name="password"><value>${database.url=jdbc:hsqldb:mydb database.DriverManagerDataSource"> <property name="url"><value>${database.hsqldb.beans. Property file: <bean id="propertyConfigurer" class="org.PropertyPlaceholderConfigurer"> <property name="location"><value></value></property> </bean> <bean id="dataSource" class="org. Constructor injection Setter injection Strong dependency contract. Suitable for beans with several properties which makes c'tor injection very lengthy.password}</value></property> </bean> datasource. Autowiring byName is more dangerous as bean names might be changed over time. Contructor arguement with same type might not be clear. Facilitates immutable property.password=password Jndi : <bean id="myDataSource" class="org.</bean> Using index is somewhat less verbose. Example : You can specify datasource details in a property file using Spring's PropertyPlaceHolderConfigurer or through JNDI.driver=org. AspectJ works at byte code level and doesn't require any framework once byte code is decorated with AOP capabilities. Use <null/> for null property : Use <null/> to initialize any property to null.config.user=hsql database.

MethodBeforeAdvice or ThrowsAdvice should be preferred over more generic MethodInterceptor if possible.are some pros and cons of spring AOP which will help you to decide. Example: public class CountingMethodAdvice implements MethodInterceptor { // The next serial number to be assigned private static long nextSerialNum = 0. For example if the method interceptor is responsible for generating unique id or count.RegexpMethodPointcutAdvisor"> 17. By default. so we need to consider thread safety issues. o private static ThreadLocal serialNum = new ThreadLocal() { protected synchronized Object initialValue() { return new Long(nextSerialNum++).support.get())).longValue(). Spring supports three types of regex method point cuts: o org. falling back to Perl5RegexpMethodPointcut on JDK 1. use more sophisticated and elegant regular expression at the application context level. Example: <bean id="crudInterceptor" class="com. This is not possible with AspectJ.JdkRegexpMethodPointcut : Java 1. which one to use: Pros: o Spring AOP doesn't require any special java compiler or special build process.3 (requiring Jakarta ORO on the classpath).Perl5RegexpMethodPointcut : Perl5 regular expression for the fullyqualified method names to match o org.out. Spring generates subclass of the target class and weave advuce around overriden method. JdkRegexpMethodPointcut will be used on JDK 1. Use a narrow window to add advice : It is recommonded not to use a borader advice when your rquirement could be fulfilled with a more narrow advice.springframework.springframework. o Target object is not modified. AspectJ requires special making them an Advisor. AspectJ and JBoss AOP supports field joinpoints as well.4 regular expression for the fully-qualified method names to match. } } public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.springframework. . AspectJ modiefies target object 18.aop. o org.4+. o Different advice could be applied to different instance of the same : Convenient class for regexp method pointcuts that hold an Advice.mycompany.println("This method is called " + getCount + " times"). private static long getCount() { if(serialNum!=null){ return ((Long) (serialNum. Cons: Spring AOP can not be applied to final methods. o Spring only supports method joinpoints. o It is possible to programmatically create proxies. } } Use regular expression advisors to fine tune interceptor scope : Instead of using broad method point cuts and filtering target methods in interceptor. o Targets are not proxied which means that the method calls on this object is not advised. } }. Be aware of thread safe issues with AOP advice : Advice instances are most often shared among threads. then consider using ThreadLocal variable with synchronized method for incrementing the count.CrudInterceptor"/> <bean id="crud" class="org.aop. 19.

Prefer static pointcut over dynamic point cut : In Spring's book of definitions static point cut refers to a pointcut that can be evaluated when a proxy is created.springframework.aop.DefaultAdvisorAutoProxyCreator"/ > An autoproxy creator bean definition is intended to change the effect of other bean definitions. DefaultAdvisorAutoProxyCreator strictly requires Advisors. They can optionally add further properties.aop. DefaultAdvisorAutoProxyCreator is powerful. Spring ease the use of ProxyFactoryBean by providing dedicated proxies such as TransactionProxyFactoryBean and LocalStatelessSessionProxyFactoryBean. specifying a target.*destroy.MyBeanImpl"> <property name="name"><value>Dave</value></property> <property name="description"><value>Good Boy</value></property> </bean> </property> </bean> Here number of child bean definitions can "extend" the myProxy definition.*create. not for access by 21. BeanNameAutoProxyCreator is good for replacing several ProxyFactoryBean. It allows control over every aspect of the proxy.mycompany. Use autoproxying for large applications : ProxyFactoryBean works well for small application but it requires more verbose configuration. Autoproxy can be created using BeanNameAutoProxyCreator or DefaultAdvisorAutoProxyCreator.<property name="advice"> <ref local=" crudInterceptor "/> </property> <property name="patterns"> <value>.Dynamic pointcuts are slower to evaluate than static pointcuts and allow less potential for optimization..springframework.ProxyFactoryBean" abstract="true"> <property name="interceptorNames"> <list> <value>interceptor1</value> <value>interceptor2</value> </list> </property> </bean> <bean id="mybean" parent="myProxy"> <property name="proxyInterfaces"><value>com. It's always necessary to evaluate them on each invocation.*..*get.mycompany.*update.*.autoproxy. Autoproxying means that depending on some configuration..framework.framework.*</value> </property> </bean> 20.mybean*</value></property> <property name="interceptorNames"> <list> <value>advisor1</value> <value>interceptor1</value> </list> </property> </bean> DefaultAdvisorAutoProxyCreator : <bean id="daaProxyCreator" class="org. Example: <bean id="myProxy" class="org. Both advisor and advices and be used in BeanNameAutoProxyCreator interceptor list.framework. Dynamic point cuts depend on runtime information such as arguement values or call stack. It examines all advisors defined in current context for mathcing pointcut methods on target object. usually inner bean. proxying is applied consistently to a number of objects.springframework.autoproxy. Criteria for static point cuts can not changed afterwards.BeanNameAutoProxyCreator"> <property name="beanNames"><value>bean1.mybean</value></property> <property name="target"> <bean class="com. . Proxies also saves code duplication in configurations.*.aop. Examples: BeanNameAutoProxyCreator : <bean id="bnProxyCreator" class="org. such as proxy interfaces.

2.xml. There are a range of reasons why you should use them. inheriting the parent bean’s properties. Exceptions marked with negative (-) sign cause transaction to be rolled back.mycompany. Scability and Remoting best practices: Please refer to arendsen's presentation on spring remoting and scalability.interceptor. This makes sense.transaction. that is. 23. 15. postcode. Place each class mapping in its own file: Do not use a single monolithic mapping document. application code or other framework objects. suburb. Specify Transaction Rollback : By default transactions are rolled back only on runtime exceptions and not on checked exceptions. state. Identify natural keys: Identify natural keys for all entities. . you can specify that a bean be a child of some other bean. Use bean inheritance to reduce XML : Using the parent attribute of the <bean> element. 4. Hibernate Best Practices 1. particularly in a team environment. Example: <bean id="businessBean" class="org. We recommend that identifiers be 'synthetic'.NameMatchTransactionAttributeSource"><props> <prop key="businessMethod1">PROPAGATION_REQUIRES_NEW.hbm.RollBackBusinessException</prop> </props> </property> </bean> You can even mark runtime exceptions as positive to prevent rollbacks but becareful while doing so as it could have adverse affects.TransactionProxyFactoryBean" lazy-init="true"> <property name="transactionManager"> <ref bean="transactionManager"/> </property> <property name="transactionAttributeSource"> <ref bean="attributeSource"/> </property> </bean> <bean id="myService" parent="abstractTxDefinition"> <property name="target"> <bean class="com.MyServiceImpl"> </property> </bean> Note: Auto proxying also helps is reducing xml definitions but auto proxying is not declarative and it is somewhat difficult to identify affected However it is a good practice to choose specific checked exceptions where you want the transaction to be rolled back based on business needs.ISOLATION_REPEATABLE_READ. generated with no business meaning.Foo in the file com/eg/Foo. Map com. Declare identifier properties on persistent classes: Hibernate makes identifier properties optional.transaction.interceptor. This encourages code reuse and simplifies refactoring. This helps is reducing XML for specify AOP advice or transaction.springframework. Write fine-grained classes and map them using <component>: Use an Address class to encapsulate street. and map them using <natural-id>. Autoproxy can be used to define transactions as well.22. 3. Implement equals() and hashCode() to compare the properties that make up the natural key. Example: <bean id="abstractTxDefinition" class="org.

is to maintain a single open persistence contact session for the whole life cycle of the application transaction. Externalizing the query strings to mapping files will make the application more portable. Do not assume. Performance will be affected if this process occurs too often. An application transaction might span several client request/response cycles.connection. It is common to use detached objects to implement application transactions. Load mappings as resources: Deploy the mappings along with the classes they map. or even by changing the order of queries and other operations within a particular transaction. 7. However. a single unit-of-work from the point of view of a user. As in JDBC.5.html that JDBC connection. You should consider implementing org. This approach frees the application code from implementing transformations to/from a Hibernate type. Use Session. you can open a Hibernate Session and usingfile:///usr/share/doc/HTML/enUS/index. You can sometimes minimize unnecessary flushing by disabling automatic flushing. Please wait until you know something is a bottleneck. some kinds of operations might benefit from direct JDBC. 10. 11.hibernate. Consider externalizing query strings: This is recommended if your queries call non-ANSI-standard SQL functions. You should also consider using named parameters in queries.hibernate. 12. but his approach should be considered a lastresort. In a three tiered architecture. however.ConnectionProvider. . that JDBC is necessarily faster. consider using long persistence contexts: Database Transactions have to be as short as possible for best scalability. Then simply disconnect from the JDBC connection at the end of each request and reconnect at the beginning of the subsequent request. it is often necessary to implement long running application transactions. Use bind variables. 6. In a two tiered architecture.saveOrUpdate() to synchronize objects with the database. consider using detached objects: When using a servlet/session bean architecture. consider providing your own implementation of org. If you need to use direct JDBC. Understand Session flushing: Sometimes the Session synchronizes its persistent state with the database. Never share a single session across more than one application transaction or you will be working with stale data. you can pass persistent objects loaded in the session bean to and from the servlet/JSP layer. 9. This way you can still use the same transaction strategy and underlying connection provider. Do not use string manipulation to bind a non-constant value in a query. If you cannot use the built-in connection providers. An appropriate alternative in a two tiered architecture.UserType. 13.merge() or Session. Use hand-coded JDBC in bottlenecks: In performance-critical areas of the system. 8. Consider using a custom type: Suppose you have a Java type from a library that needs to be persisted but does not provide the accessors needed to map it as a component. Use a new session to service each request. Do not manage your own JDBC connections: Hibernate allows the application to manage JDBC connections. always replace non-constant values by "?".

In fact.Always use Hibernate. because when you map an association to a primary key. Most of the time you need additional information stored in the "link table". all the associations defined at composite key will be eagerly loaded. second. roll back the Transaction and close the Session. it is much better to use two one-to-many associations to an intermediate link class. 17.find on this object. everytime that you execute a session. or a disciplined assembly phase to avoid problems with unfetched data: Hibernate frees the developer from writing tedious Data Transfer Objects (DTO).get() or a query instead. Hibernate eliminates the first purpose. Think of your business methods as having a strict contract with the presentation tier about what data is available in the detached objects. use a query with a left join fetch. Combine the DAO and Thread Local Session patterns. not associations. however. For example. 16. This is not a limitation of Hibernate. It is a fundamental requirement of safe transactional data access. When an exception occurs. they implicitly define an assembly phase where all data to be used by the view is fetched and marshalled into the DTOs before returning control to the presentation tier. they work around the problem that entity beans are not serializable.initialize(property) before trying to access the lazy properties. It is not appropriate for an application with five tables. If you do not do this. almost all associations must be navigable in both directions in queries.14. Use the open session in view pattern. 15. do not use Session. most associations are one-to-many and many-to-one. use Session. Use proxies and lazy collections for most associations to classes that are not likely to be completely held in the second-level cache. Prefer bidirectional associations: Unidirectional associations are more difficult to query.Composite keys must always be mapped only by identifiers. When join fetching is appropriate to a particular use case. This advice is. In a traditional EJB architecture. DTOs serve dual purposes: first. You can even have some classes persisted by handcoded JDBC associated to Hibernate via a UserType. you should proceed cautiously when using any other association style. Do not use exotic association mappings: Practical test cases for real many-to-many associations are rare. Consider abstracting your business logic from Hibernate: Hide Hibernate data-access code behind an interface. intended for "sufficiently large" applications. In this case. you will still need an assembly phase. Hibernate Mappings Best Practices Some hibernate simple rules: 1 . Unless you are prepared to hold the persistence context (the session) open across the view rendering process. For associations to cached classes. Do not treat exceptions as recoverable: This is more of a necessary practice than a "best" practice. explicitly disable eager fetching using lazy="false".Always provide a reasonable BatchSize 3 . Hibernate cannot guarantee that in-memory state accurately represents the persistent state.load() to determine if an instance with the given identifier exists on the database. For this reason. where there is an a extremely high probability of a cache hit. Prefer lazy fetching for associations: Use eager fetching sparingly. 2 . 19. . 18. In a large application.

Always prefer to use HibernateCallback in conjunction with the hibernateTemplate.1 . 9 . 6 .3 . 10 . before returning the logged UserDetails 1. executes the login 1. 5 .merge mechanism instead of session.1 . and the authorization being managed by the architecture. or if the authorization needs to be added to the SSO as well. adds the returned UserDetails to the "userSessionCache". to prevent abnormal use of session (like the infamous NonUniqueObjectException).The SSO first verifies if the IP is valid for authentication 1. Some thoughts about Single Sign On Application/service 1 .Always prefer to use the session.2 .3. for cache reasons.User sends the token to the SSO requesting authentication 1.update or session.3.Using the right Collection for the right association needed (Set<Entity> if you have to provide a collection without duplications.3. returns null The main question is if the SSO needs only to maintain the authentication. and to prevent HQL injection 7 . to provide extensibility on the points that hibernate has poor or no available resource (like providing named queries. List<Entity> if you can have duplicity.saveOrUpdate.If the username/password is in the cache. stored procedures executions.4 .If the login is unsucessful.If the username/password is NOT in the cache.1 .Entity> if you have to provide key/value pairs).2.2 .The SSO then verifies if the Username/Password is not on the cache 1. Map<Key.Provide acess to the hibernate API on the Data Access Layer. I'll provide the needed .excluding all unused data to be performant.If the login is sucessful.Always prefer to use named queries instead of string parsed queries.3. then just retrieve the UserDetails 1.Use @Cache on class level and on association level. native queries.2 .Basic SSO authentication 1. updating lock modes on the fly and using the evict and initialize features.Using the HQL correctly to load only what is needed .2. 8 .