Spring annotations contradict my design rules

Overview
Using

  • Spring 3.0.1 (annotation configuration)
    • The current configuration uses CGLib as a proxy creator, but this is not my preference
    • A transaction is an annotation configured without any special settings.
    • All configuration is done with annotations ( @Service , @Transactional , @ManagedResource , @Inject , etc.)
  • Hibernate 3.5 (objects are annotated using javax.persistence)

Management Highlights

  • Each bean annotated using @Repository or @Service must have an interface
  • DI Constructor (if reconfiguration is not required)
    • The constructor has default visibility ( Foo(Bar bar) {...} )
    Fields
  • Beans are final (when reconfiguration is not required)
    • Doesn't result in a default constructor
  • Implementations are displayed by default with the final modifier ( final class Foo )

Problem

  • CGLib cannot proxy final classes
  • CGLib requires a default constructor (empty)
  • Some services must be open via JMX
  • MBean exporter cannot work unless CGLib is proxied
  • Some @Transactional @Service accessed through a facade service, which requires more than one service to be included in facade transactions (for example, an observer service through 2 application components).
  • Some interfaces have more than one implementation (which is currently @Qualifier different)
  • Future reference point (or pleasant to use) - for each application module there will be a beanRefContext.xml file for setting the internal context of the application

When I was working with the XML configuration, I was able to enforce all the recommendations presented above, but when switching to annotations, it seems that Spring is wrong.
The developers in my group prefer the configuration of annotations (it seems easier to connect and write new code), but I noticed all kinds of “hacks” that they introduce into the code to prevent Spring application context failures.

Question (s)

  • Are there any best practices that I must follow when using the annotation configuration?
    • When using more than one implementation per interface (attempt to reduce the use of @Primary or @Qualifier )
    • When using @Transactional
    • When using @ManagedResource
    • When using the combination above
  • Is there a way to stop working with CGLib, save the annotation configuration and still be able to export my annotated MBeans?
  • What is a suitable implementation to preserve most (preferably all) of my recommendations?
+4
source share
2 answers

I came up with the following solution (for questions No. 2 and No. 3) in order to be able to apply my design recommendations and continue to use the configuration based on annotations:

  • Each dependent project (Maven module) has its own ApplicationContext
  • Each dependent context of a project application is defined in beanRefContext.xml
  • These application contexts are loaded into the hierarchy using the Spring context hierarchy mechanism.
    • This step is actually not fully supported by Spring and requires additional work.
  • Since my application is multi-level, I can disable CGLib in all my modules except for the JMX level (I can live with it :-)).

The above steps also allowed me to reduce the execution time of Spring tests (each module is loaded only with a subset of beans).

As a practical guide (for question number 1), if the interface has more than one implementation, I place @Primary on the widely used one and the other clients, requiring a different implementation, conducting a bean using @Qualifier .

+3
source

Answer to point 2) You can use AspectJ instead of CGLib.

+1
source

All Articles