I use configuration classes (Java classes with the #Configuration annotation) to configure my beans. In general I want to avoid stereotype annotations (like #Service and #Component) and component-scanning my whole project.
Are there any best practices on where to put my Configuration classes? There are different setups that come to my mind:
Put configuration classes in a separate package on the root level of your module
- src
- config
- SomeServiceConfiguration.class
- dao
- controller
- service
- SomeService.class
Where you register a SomeService bean in SomeServiceConfiguration. My biggest problem with this is that you lose the chance to use visibility modifiers. Every class has to be public in every package to construct the bean, this can be a real bummer in bigger projects. The upside is that I can obviously just scan the config package to register my beans.
Put configuration classes in the same package as the class you want to register
- src
- dao
- controller
- service
- SomeService.class
- SomeServiceConfiguration.class
This allows you to use visibility modifiers, but managing the configuration files become a hassle. Your configuration files are now littered through your whole application, you will have to put in more effort to manage them. Although I start to think that this might be the favorable approach.
Are there any methods preferred by the community? Which one is preferred for bigger projects? Which one scales the best? Please note that I don't want to use stereotype annotations.
but managing the configuration files become a hassle. Your configuration files are now littered through your whole application, you will have to put in more effort to manage them
Disagree. If you know you have to modify the definition of a specific controller bean you know where looking --> controller/config
It could depend on the number of beans you have... you should avoid large class with lot of beans definitions... So depending on that It will be better to split or not...
I am refactoring an application using Spring by moving some shared components (a webservice client) into a library. The components cannot work on their own so still need some beans from the application that uses the library. What is the best practice for this?
I have created a #Configuration class so the application only needs to #Import it to use the library, but the application also needs to supply a Jackson ObjectMapper and a Settings object containing how to contact the webservice. I autowire the ObjectMapper and Settings beans into various beans used in the library. The application uses the library by injecting the Client into its code and calling it.
This works, but I'm not sure it's the right style. In IntelliJ IDEA as I develop the library, it complains that the beans the library injects don't exist with a red underline, which is true, they don't exist. But normally when I see red all over files that cannot be resolved, that tells me maybe I'm not doing it the right way.
The library needs to be used with applications using Spring 3 and 5. What is the proper way for a library to ask for things like ObjectMapper when it's not appropriate to define its own (because the app will already have Jackson), and "proprietary" beans like the Settings object?
Your question is a bit broad but hopefully I can give you a hint to the right direction.
The components cannot work on their own so still need some beans from the application that uses the library. What is the best practice for this?
First: This components should use an interface instead of some concrete beans.
Second: If you have a reusable library then this typical needs some configuration, that can not been part of the library itself because it depends on application that use that library
Third: because of second (and first): your library should not been based on any form of auto wiring, instead your library should been based on explicit (or default) configuration.
And this solve the problem. Use interfaces and an explicit configuration of your library in your application. As well as add an good documentation of the needed configuration to your lib.
Using inspiration from #Kayaman and #Ralph, I decided it's not appropriate to expose Spring as a part of a library to be used directly from the application's context. I realize now it's also not appropriate because the library could define duplicate "private" beans it did not want to expose. I was overthinking it. If I wanted to use Spring, I found out I could do this:
public class Factory {
public static Client createClient(ObjectMapper mapper, Settings settings) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("mapper", mapper);
beanFactory.registerSingleton("settings", settings);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(beanFactory);
ctx.registerBean(ClientConfiguration.class);
ctx.refresh();
return ctx.getBean(Client.class);
}
}
Essentially, it's OK to use Spring as an implementation detail. Since the configuration I made exposed only one bean, it makes sense as a factory method. In the application I would create a method like this:
#Bean public Client makeClient(ObjectMapper mapper, Settings settings) {
return Factory.createClient(mapper, settings);
}
Of course the Bean method would have ObjectMapper and Settings injected in from the application's context, or could be inline constructors for ObjectMapper/Settings.
Instead, what I decided was since the client had few enough beans and none were lazy, I just removed Spring annotations entirely and just built the object graph by hand in almost as much code as the spring context took. Now the library has the benefit of not requiring Spring at all at runtime, in a supposed non-Spring application.
Spring MVC uses mainly annotations to configure its Controllers, as far as I know, the only way to configure a Controller in Spring WITHOUT Annotions (only XML) is extending the AbstracController (or Similar Controller classes) and currently all this classes are deprecated for Spring 3.
While I think that is a good idea to drop support for this classes, mainly because extending this classes creates controllers that hardly depend of Spring as a dependency, I don't understand why Spring doesn't provides a configuration like Struts Actions (Actions in Struts 2 don't extend any weird class so they dont' have any dependency of Struts)
Why Spring MVC doesnt provide a clean POJO-style configuration like Struts 2 Actions via XML?
Why to drop support for XML configuration on MVC using ugly Annotations? why not to drop it in ALL Spring Proyects?
The main problem with the XML/POJO approach is that there is no way to tell from looking at your code that special magic is going on.
Instead of seeing
#SomeAnnotation <<-- Oh, golly there is something special happening here.
java code...
You see
Java code <<-- special magic hidden in XML file (or not, no way to tell)
<<-- are these linked? no idea..
<<-- is something going on? let me go and search....
If changes happen to the source code, the XML may (or may not be) out of sync.
With the annotations you can update the java code and the spring annotations at the same time.
Yes it's cluttered but at least it's easy to sync the two.
Annotations are hard enough to grok when they're in your face. If they're not even visible the mental burden for us non-angry developers is really too much to bear.
why not to drop it in ALL Spring Projects?
Wouldn't that be sweet....
using ugly Annotations?
Obviously the question has been asked: Is there a way to hide annotations in Eclipse?
And the answer is: https://stackoverflow.com/a/2569646/650492
Sort of... does that help?
I am currently working on a solution for testing EJB 3 Services with JUnit.
(Yes, I have looked at ejb3unit but it doesn't work for me. Yes, I have looked at container-integrated testing with openEJB but that didn't work out neither..)
So my question is what would be the way for resolving #EJB annotated Dependencies? And I don't mean by using a DI Framework like Weld, Guice or Spring. The solution should be applicable for plain old JUnit Tests -> without using an EJB Container like JBoss, Glassfish or openEJB.
I was able to replace the injection of the entity manager via #PersistenceContext with a little hack using java reflections. So how would I do that for dependencies with #EJB annotation?
(I wouldn't mind building and resolving the dependency tree myself, just looking for ideas ;) )
Greetings from Germany,
p.s.
Not sure why you're against the solution you proposed.
I was about to offer stuff like Arquillian, but hey - you don't want to have a container involved.
I just want to be sure about the reason you don't want container, before I move on to some ideas (though I did not test them) -
With JBoss AS 7.x deployment time of enterprise application servers was vastly reduced,
Not to mention that with Arquillian you have a deployment API, and you can decide what you will deploy (i.e - deploy for example just a single bean for a given test).
However, I do respect you question, so here are some ideas -
A. You mentioned you managed to inject an EntityManager using reflection - how did you do that? Why not apply the same to your beans?
B. If you're encountering problems with A, why not develop your own injection code , based on cglib , for example (in order to create Proxy not just for interface, but also for classes).
This way, when an object of the class is created,
you will be able to intercept the default CTOR, and scan for fields annotated with #Ejb.
I would suggest using some sort of configuration file that maps for each bean interface how to instantiate an appropriate class, and run this flow recurisevely (as the injected bean might have a field with #EJB annotation as well).
Pay attention that if you decide to use this method of work, you'll be implementing some sort of "mini dependnecy injection framework" - besides the fact that personally I would be interested in seeing your code ( :) ) I think you should carefully think why you don't want to use an "already made solution.
Note regarding the Arquillian suggestions, that still requires an EJB Container like JBoss, GlassFish, or OpenEJB.
If the problem is just finding and including all the dependencies, try this jar that includes all the required dependencies for EJB Lite:
http://repo1.maven.org/maven2/org/apache/openejb/openejb-lite/4.0.0/openejb-lite-4.0.0.jar
Include that in your test classpath (no other jars needed) then just boot the embedded container:
EJBContainer container = EJBContainer.createEJBContainer();
MyBean bean = (MyBean) container.getContext().lookup("java:global/myModleName/MyBean");
Working example here
Have you look at Arquillian?
You can find all the documentation on the project page: http://www.jboss.org/arquillian.html
Recently in our team we started discussing using spring annotations in code to define spring dependencies. Currently we are using context.xml to define our dependencies. Would you give me some clues for either approach, and when one is better to be used?
Edit: I know this seems a duplicate question to a more-general one, but I am interested in the impacts of annotations vs configuration for dependency injection only, which I believe would have different answers and attitude than the general question.
After reading some related posts here and having further discussion in the team we come to the following conclusions. I hope the would be useful to others here.
About XML configuration (which we are using up to now), we decided to keep it for dependencies defined by libraries (regardless if being developed by us, or by third parties).
Libraries, by definition, provide a particular functionality and can be used in various scenarios, not necessarily involving DI. Therefore, using annotations in the library projects we develop ourselves, would create a dependency of the DI framework (Spring in our case) to the library, making the library unusable in non-DI context. Having extra dependencies is not considered a good practice among our team (an in general IMHO).
When we are assembling an application, the application context would define the necessary dependencies. This will simplify dependency tracking as the application becomes the central unit of combining all the referenced components, and usually this is indeed where all the wiring up should happen.
XML is also good for us when providing mock implementations for many components, without recompiling the application modules that will use them. This gives us flexibility when testing running in local or production environment.
In regards to annotations, we decided that we can benefit using them when the injected components will not vary -- for instance only a certain implementation for a component will be used troughout the application.
The annotations will be very useful for small components/applications that will not change or support different implementations of a dependency at once, and that are unlikely to be composed in a different way (for instance using different dependencies for different builds). Simple micro-services would fit in this category.
Small enough components, made up with annotations, can be used right out of the box in different projects, without having the respective applications to cover them in their XML configuration. This would simplify the application dependency wiring for the application and reduce repetitive setups.
However, we agreed that such components should have the dependencies well described in our technical documentation, so that when assembling the entire application, one can have an idea of these dependencies without scrolling through the code, or even loading the module in the IDE.
A negative side effect of annotation-configured components, is that different components could bring clashing transitive dependencies, and again it is up to the final application to resolve the conflicts. When these dependencies are not defined in XML, the conflict resolution approaches become quite limited and straying far from the best practices, if they are at all possible.
So, when going with annotations, the component has to be mature enough about what dependencies it is going use.
In general if our dependencies may vary for different scenarios, or a module can be used with different components, we decided to stick to XML. Clearly, there MUST be a right balance between both approaches, and a clear idea for the usages.
An important update regarding the mixed approach. Recently we had a case with a test framework we created for our QA team, which required dependencies from another project. The framework was designed to use the annotation approach and Spring configuration classes, while the referenced project had some xml contexts that we needed to reference. Unfortunately, the test classes (where we used org.testng with spring support) could only work with either the xml or java configuration classes, not mixing both.
This situation illustrates a case where mixing the approaches would clash and clearly, one must be discarded. In our case, we migrated the test framework to use spring xml contexts, but other uses could imply the other way around.
Some advantages of using XML configuration:
The XML configuration is at one place, instead of being scattered all over the source code in case of annotations. Some people may argue that IDEs like STS allow you to look at all annotations based configuration in one place, but I never like having dependencies on IDEs.
Its takes a little more efforts to write XML config, but it saves a lot of time later when you search for dependencies and try to understand the project.
XML keeps configuration well organized and simple. Hence is easier to understand, it helps new relatively inexperienced team members get up to speed quickly.
Allows you to change the config without a need to recompile and redeploy code. So it is better, when it comes to production support.
So in short XML configuration takes a little more efforts, but it saves you a lot of time & headache later in big projects.
2.5 years later:
We use annotations mostly these days, but most crucial change is that we create many small projects (instead of a one big project). Hence understanding dependencies is not a problem anymore; as each project has it's unique purpose and relatively small codebase.
from my experience, I would prefer(or rather am forced by limitations) to use a combination of XML and annotation based DI . If I need to inject a Map of elements inside a bean , I would have to define a util:map and autowire it . Also, I need to use XML DI to inject datasource into the sessionFactory if I have multiple datasources and so on . So a combination of both would be requited .
I prefer the usage of component-scan to autodetect the services and Dao . This cuts down a lot of Configuration (We cut down the configuration files by around 50% switching to component-scan). Annotation based DI supports both byName(#Resource) and byType(#Autowired).
In short my advice to be to go for a fixture of both . I feel that more annotation support will definitely be on cards in future Spring releases.
Take a look at this answer here: Xml configuration versus Annotation based configuration
A short quote directly from there:
Annotations have their use, but they are not the one silver bullet to
kill XML configuration. I recommend mixing the two!
For instance, if using Spring, it is entirely intuitive to use XML for
the dependency injection portion of your application. This gets the
code's dependencies away from the code which will be using it, by
contrast, using some sort of annotation in the code that needs the
dependencies makes the code aware of this automatic configuration.
However, instead of using XML for transactional management, marking a
method as transactional with an annotation makes perfect sense, since
this is information a programmer would probably wish to know.
EDIT: Also, take a look at the answers here: Java Dependency injection: XML or annotations They most probably target the area of your interest much better.
From my own experience annotations better than xml configuration. I think in any case you can override xmls and use annotations. Also Spring 4 give us a huge support for annotations, we can override security from xml to annotations e.t.c, so we will have not 100 lines xml but 10 lines Java Code.
Are annotations better than XML for configuring Spring?
The introduction of annotation-based configurations raised the
question of whether this approach is 'better' than XML. The short
answer is it depends. The long answer is that each approach has its
pros and cons, and usually it is up to the developer to decide which
strategy suits them better. Due to the way they are defined,
annotations provide a lot of context in their declaration, leading to
shorter and more concise configuration. However, XML excels at wiring
up components without
touching their source code or recompiling them. Some developers prefer
having the wiring close to the source while others argue that
annotated classes are no longer POJOs and, furthermore, that the
configuration becomes decentralized and harder to control.
No matter the choice, Spring can accommodate both styles and even mix
them together. It’s worth pointing out that through its JavaConfig
option, Spring allows annotations to be used in a non- invasive way,
without touching the target components source code and that in terms
of tooling, all configuration styles are supported by the Spring Tool
Suite.
my personal option is that xml is better since you have all at one place and you do not need to deep into your packages to search the class.
We can not tell which method is good, it depends on your project. We can nither avoid xml nor annotation. One advantage of using xml is that we can understand the project structure just seeing the xml context files, but annotation reduces lots of meta configuration. So I prefer 30% xml and 70% annotation.
By using XML, you prevent code from being polluted with framework-specific annotations and thus creating an undesired coupling. Keep the framework at the application boundary so you can always replace it should the need arise.
Frameworks come and go, but many applications live for decades. Fortunately, Spring is a non-invasive framework and doesn't bend your architecture. Keeping the configuration in XML will make it even more detached from your application.
Remark: in order to benefit from all this, your application should be well-designed in the first place.