This page last changed on Dec 10, 2007 by mryall.
These are guidelines related to the development of Confluence. The guidelines mainly apply to Atlassian employees, but reading them should provide insight for third-party plugin developers as well, so we decided to make them public.

All new Spring component code should follow these guidelines. If you come across existing code that doesn't follow them, consider refactoring it to do so.

For an overview of how Spring is used in Confluence, see Spring IoC in Confluence.

General Rules

  • For singleton components, prefer constructor-based injection with final fields for dependencies.
  • If you have too many components to fit comfortably in a constructor, that's a sign the design is broken.
  • Autowiring should only be used for transient, programatically constructed objects like actions and plugins. Never autowire anything that's defined in a config file.
  • If a component is rarely used (i.e. the upgrade manager), consider giving it prototype scope instead of singleton.
  • Avoid circular dependencies. If you see a circular dependency, ask yourself:
    • Can this problem be solved using events?
    • Can this problem be solved by having one party register a callback?

Transaction Management

  • Transactions should be wrapped around the manager layer.
  • Use the old-style Spring 1 transaction configuration syntax with explicit proxies - the Spring 2 pointcut syntax seems to slow down container startup (and thus test-running) by a factor of ten

Profiling

  • Managers and DAOs should be wrapped by the profiling interceptor
  • If you're wondering whether a bean should be profiled or not, veer towards yes

Notes

Could we use some kind of funky XML Spring extension so we could declare a bean like this and have the extension apply the relevant interceptors?

<bean name="blahManager" class="com.example.BlahManager" atl:txn="defaultManagerTxn" atl:profile="yes"/>
Document generated by Confluence on Dec 20, 2007 19:02