We’re making changes to our server and Data Center products, including the end of sale for new server licenses on February 2, 2021 and the end of support for server on February 2, 2024. Learn what this means for you.
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.
Autowiring should only be used for transient, programatically constructed objects like actions and plugins. Never autowire anything that's defined in a config file.
For singleton components, prefer constructor-based injection with final fields for dependencies.
Always specify indexes for constructor arguments.
If you have too many components to fit comfortably in a constructor, that's a sign the design is broken.
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?
Why use explicit constructor injection?
It fails fast. If a dependency is added, removed, missing, renamed, misspelled or the wrong type, you find out with a clear error message during system startup not a NullPointerException much later.
With the amount of components in our Spring context, the introspection required to perform autowiring (or even to resolve the order of components in a constructor) contributes significantly to the startup time of the application.
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
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
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?