I am starting to learn about the Spring framework. I have seen two ways to configure a web application, one uses a web.xml to configure the servlets ect. The other uses a Java class that implements a WebApplicationInitializer and is annotation driven.
I was told that, "XML is the old way, no new project should use XML anymore". Can anyone tell me why this is? Lots of online resources quote "Convention over Configuration", however, using the online learning tools I have access to, the vast majority of examples are using xml configuration. I am finding it very difficult to find relevant examples with Java configuration.
I would also like to know what the pro's and con's of using one over the other are? If it it easier to find resources based around xml configuration, then would it be destructive to future job prospects to side step the Java configuration and focus on xml?
The advantages of Java Config is the type safty. The Compiler can check if you wire your application correctly (based on the types). Refactoring is a little bit easier.
Using XML configuration this can only checked during runtime.
My own opinion is that there is not a big difference between the two approches. You only "tell Spring" differnetly how to wire the application. The Java Config brings in some nice features (e.g. Spring Security Config), but also hides some "magic" which is sometimes harder to understand.
You may also have a look at earlier questions about this topic.
In Projects we still do here a lot of XML configuration which works pretty well. New Configs are often written as Java Config and integrated into the "lagacy" configs.
Related
Hello stackoverflow Users,
I have found myself working on a Java EE Web Application and I know for a fact that my application is going to be deployed into multiple environments. Each environment may have slightly different configuration of some features, e.g. remote web-service URLs. Additionaly, I would like - if possible - to have the following 2 properties met:
Per environment config should not in web-application repository
This is because I feel it does not belong there. I would not want to manage n-configurations next to my source code. Moreover, if there are secrets there, I would not want every developer to see them...
Enforce completeness of configuration
If I say that I need a certain configuration parameter/resource then it would be meaningless if it was not provided. I would not want my application to start in such case.
Please, can somebody more knowledgable and experienced help me and nudge me into the right direction?
My findings so far
Naturally, I have spent some time searching the answer already ...
Spring framework
I know that spring provides an Environment class as an abstraction of environment-specific configuration. However, I am not using Spring framework, nor does it describe how to put this configuration outside of the web applicatoin.
Java EE JNDI Service
According to the Java EE platform specification, the right way to do it would be to use env-entry, resource-ref and resource-env-ref elements in my WEB-INF/web.xml and have them bound/set to values in the web app container configuration.
This actually sounds very good, except that I don't know how to enforce the completeness of this configuration. I mean, I declare the above mentioned elements, to tell the deployer that I need them, yet I see (tested on tomcat) that application still deploys (and works incorrectly) when some, say resource-env-ref, is not bound.
I don't know how to achieve it tbh, however, if there is nothing better, it still feels like the best thing I could find. :-|
I have taken the JDNI approach.
I have added validation of configuration by introducing a custom ServletContextListener implementation.
Currently my spring configurations are in a xml file (the traditionaly way).
One thing that i like about this is during deployment I can deploy a different version that has my production settings, or say in a test environment I can have test settings there.
I like the idea of having things configured in a class, but that will get compiled into my war and then it won't be as flexible.
Is there a way around this?
Java configuration is great and it has several advantages:
refactoring-friendly
type-safety
much more flexible (you can write any Java code, not being bound to XML semantics and capabilities).
I can deploy a different version that has my production settings, or say in a test environment I can have test settings there.
Investigate Spring #Profiles. They are orthogonal to your question (work both in XML and #Configuration) but are best suited in your situation.
Those are the only two ways available. If you don't want configuration baked in code, then you have to go with xml.
The spring reference manual includes a section on combining both Java and XML configuration. See http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-java-combining
If you tend to be more XML centric you can bootstrap your app using XML and then introduce Java config as needed in an ad-hoc fashion. This might be a good way to ease into it. You might decide to go Java config all the way.
I'm looking for some best practices when using Spring 3 annotations.
I'm currently moving to Spring 3 and from what I've read so far I see a lot of accent placed on using annotations and moving away from XML configuration.
Actually what is recommended is a mix of both styles, with annotations covering things that won't change often or from one run to the next (e.g. a #Controller will remain like that for the life time of the application), while the things that change and must be configurable go into XML (e.g. a mail smtp address, endpoints for web services that your application talks to etc).
My question is what should go into annotations and to what extent?
At which point annotations make things harder instead of easier? Is the technology (Spring 3) fully adopted as to be able to make such statements or does it take some more time for people to gain experience with it and then reflect on the issue?
It is always difficult to get real advanced information.
The easy tutorial with "look on my blog, I copied the hello word tutorial from Spring Source website... Now you can put fancy annotations everywhere, it the solution of all of our problems including cancer and starvation." is not really usefull.
If you remember right spring core had several purposes, among them:
to be non intrusive
to change any
implementation/configuration of a
bean at any time
to give a centralized and controlled
place to put your configuration
Anotation fail for all theses needs:
They introduce coupling with spring
(you can use standard anotation only
but as soon as you have at least one
spring anotation this is no longer
true)
You need to modify source code and
recompile to change bean
implementation or configuration
Annotations are everywhere in your
code. It can be difficult to find
what bean will be really used just by
reading the code or XML configuration
file.
In fact we have shifted our focus:
We realized that we almost never
provide several implementations of
our services.
We realised that being dependant of
an API is not that bad.
We realized that we use spring not only
for real dependancy injection
anymore, but mainly to increase
productivity and reduce java code
verbosity.
So I would use anotations when it make sence. When it is purerly to remove boilerplate code, verbosity. I would take care of using the XML configuration file for thing that you want to make configurable, even if it is only to provide a stub implementation of the service in unit tests.
I use #Value for properties that are configured in external properties file via PropertyPlaceholderConfigurer, as kunal noted.
There is no strict line for when to use xml, but I use xml:
when the bean is not a class I control
when the object is related to the infrastructure or configuration rather than to the business logic.
when the class has some primitive properties that I would like configurable, but not necessarily via externalized configurations.
In response to your comment: spring is very widely adopted, but "good" and "bad" are very subjective. Even my lines are not universal truths. XML, annotations and programmatic configuration all exists for a purpose, and each developer / company have their preferences.
As I said - there is no strict line, and no universal good practice for annotations.
Annotations are surely the way by which "newer" programming in java will continue. I use annotations for various uses...like #Scope for scope of bean, #Required for making dependency necessary, #Aspect for configuring advices,#Autowired for constructor injection using annotations. Since spring 2.5, annotation support has been good.
See here for spring tutorial, where annotation based issue are covered here.
I think that two cases that the usage of annotations could cause some problems. Firstly, if you want to write complex named queries (JPA) in your entities. I saw some entity code samples and asked myself whether the code is really java code or not. To many metadata in program code will reduce the readability of it which kills clean code principles.
Second problem is portability between JVM versions. Annotation is a feature 1.5+. If your software should support earlier JVM versions, then you may not use these.
Anyway, you can enjoy with annotations everytime without having any doubt and spare your time not changing IDE tabs to check XMLs if the property is still there or not, or entered correct etc.
For very small projects you could still XML version if you haven't too many stuff to be declared in spring. But, if you are in a huge project, the things could be very troublesome if you had 10 xml configs.
This will perhaps not help you much but at work they don't want to use autowiring because it needs a classpath scan (but that can be package-defined i think). So it increases the startup time of the application according to the size of the project.
I have got my hands dirty in Spring Roo, I have managed to do the persistence set up for Oracle Database. Although I have gone through the Roo documentation
but it not enough for me to understand the working of this framework.
I'm not aware of Spring-MVC ,Spring-Web Flow and AspectJ rather I have knowledge of frameworks such Struts, Tapestry and GWT. Could this be a hindrances in learning Spring Roo.
Please advice as I'm running out of patience of hacking the generated code by Spring Roo. Is it good idea for me to jump in a Spring Roo project?
The Spring Roo is more than a code generator. If you make changes in your Entities, it will change the codes automatically. More like a stateful code generator. First you need to find out the commands available in Spring Roo to configure a project.
You can configure which database you want to use, which orm you want to use, whether you want to use unit-tests or which view technology you want to use. Give the commands and Roo takes care of it. You don't need to worry about which libraries to download, how to make pom file for Maven.
The configurations you got using Spring Roo is quite a standard one. I used it in the previous projects. The code generated is not optimal, for example , you can use generic daos instead of Roo generated DAO if you consider the generated codes are verbose.
Another example says, in Flex, you can use Roo to generate configurations for the communication between Flex client and J2EE server. For my case, I use parsley and observer patterns for flex client instead of the codes generated by Spring Roo. But by looking at the codes what the Roo-Flex team wrote taught me quite a lot of things too. The same things goes for GWT and Spring MVC.
So what am I saying is that as the programmers, we need not only to code we also need to read what the other wrote too . I strongly believe that it is a good way to learn and share best practices. You might get some boilerpate codes, but if you know how to apply design patterns or can enhance on them, those codes will become the gems.
Learning curve ? Not at all. The commands are as simple as DOS commands.
Spring ROO is just a command line interface for generating a lot of the boiler plate code you usually need to write to get things done in java projects.
If you want to add GWT into your project, just type "gwt setup" after you've created your models and you have full-on GWT support in your project.
The default view being generated in Roo uses Apache tiles, similar to Struts, Tapestry and JSF.
If you want to use web flow, just type in "web flow" and it'll be integrated for you, for struts support, you'll need a plugin, I've seen a couple of them floating around the web, haven't tested any of them; same goes for tapestry, you can either use a tapestry plugin or do the integration by hand.
AspectJ in the context of Roo generated scaffold is used to hide all the boilerplate code that makes code look like spaghetti, you can move code out of the aspectJ generated files into your own java files and modify them if you need to.
As for the hacking, it takes a lot of patience and time to fully understand where you should change stuff and where you shouldn't, all I can say is, happy hacking :-)
springroo is based on many technologies, but all what springroo does is to help you to generate scaffolding code using lots of addons you can install
at least it's my view of this framework after three days of learning it
We basically need to be able to adjust behaviour at start-up time, by providing desired classes to be produced by various factories inside our application (to avoid the hard binding of the "new" operator).
I am aware that this is provided by several large frameworks, but I was looking for something easily used by a stand-alone Java application without being gigantic.
Any suggestions?
Edit: It is my experience that frameworks tend to grow big as part of maturing (and complex too). I need this to be retrofittable to a legacy application as part of major refactoring (technical debt), so simplicity is essential of the used libraries. I do not mind having to do a bit of coding in our application, but it must be very visible what is going on. AOP has a tendency for moving stuff out of the way, and that may make the application harder to maintain.
Edit: We have now reached the point where we actually need to make a decision. The application will probably live for decades so we need to make a reversible decision with a framework that will be maintained for hopefully as long. I really like the static type check available with Guice, but not that the annotations bind explicitly to Guice instead of being external like in Spring. I also like that code appears to be more concise when using Guice as opposed to Spring. We need something that is robust and helpful. We do not need more than just DI at the moment. Is there a use case that definitive says go for one of these?
Edit 2011-07-27: The final decision was to use the JSR-330 API in code, and choose on a per-project basis if to use Spring, Guice or Weld. For stand-alone applications Guice has worked well so far as the JSR-330 implementation.
You can always use Spring Framework 2.5. It is a big one, but if you planning to use only DI you can use spring-core and spring-beans modules, which are pretty small (ca. 500KB and 300KB).
There is also Google Guice 2.0 which comes with a package with only basic stuff (no AOP) and it's 430KB.
Have you looked at the Google Guice framework? It's pretty lightweight and annotation-based, avoiding XML configuration files
There's also Pico- and Nano-container (from codehaus) which are quite lightweight although the last time I looked (admittedly a few years ago) the documentation was lacking.
I must say that I agree with others about what I assume is your presumption that Spring is massive and confusing. It's really a very simple IoC container and to be recommended.
There are a couple I know of you might find useful:
PicoContainer
Plexus (used in Maven)
I've found Plexus very useful in standalone apps as it has optional utility components for CLI interaction.
By "gigantic" I'm going to assume you're referring to Spring, but that's unfair, since you can cherry-pick the bits of Spring you want to use. If all you need is the IoC container, just use the appropriate JAR files and the appropriate bit of the API, and ignore the rest of it.
Most answers so far seem to be concerned with the size of the jar files to be added.
However I think the more important question is the impact on the project: How many lines of code must be added/changed in order to use the framework?
Even the "big" spring framework is actually very easy to use:
You basically need:
a xml file that describes your factories.
one line of code to initialize the container by loading the xml file
The nice thing is that spring is non-intrusive. So you do not have to implement specific interfaces or add any specific annotations or imports to your classes.
At best the single spot where you actually initialize the Spring container is the only
place in your application that has an actual dependency to spring classes.
I would strongly suggest to take a look at Spring ME. Although originally meant to be a way to use Spring on Java ME applications, it also works fine for standalone applications.
True, it doesn't give you all of the bells and whistles that Spring (Full) has to offer, but then again, Full Spring is much much more than a simple dependency injection framework.
On the plus side: it's based on a (compliant) subset of Spring's configuration files, and the footprint of the runtime is 0%. In fact, there isn't any. Spring ME will take your application context, and turn it into a class that has no dependencies on classes other than your own.
What's wrong with Spring?
These days it's packaged pretty well so you wouldn't need to take the whole kit and caboodle.
As an aside, I'm not a fan of the annotation based injection frameworks. This is because the annotations are bound to the class rather than the instance, the later being a pre-requisite, imho, for DI. This means every instance of a given class gets the same object(s) injected, which seems to defeat the point.
Also consider that DI doesn't even need a framework, what's wrong with your main method wiring together the application?
If you want something maximally simple and appropriate, then write some code that does what you want done. Presumably this involves wiring together factories based partly on fixed logic, and partly on run-time settings.
This has the advantage that the set of possible run-time configurations is known, and so documentable and testable.
It has the disadvantage that an deploying an unanticipated logic change inherently takes an extra second or so of compile time, and (more significantly) can't be sneaked into production without full testing by disguising it as 'just a configuration change'.
About a year ago I asked myself a question very like this. So I spend a few hours reading the Spring and Guice documentation. After about an hour with Spring I was left feeling that I could get a basic web app going, but had no idea how to use it in a stand alone application. After an hour with the Guice document everything had clicked and I could see just how I to do what I wanted to get done.
Now on to recommending Guice? Well no. What does your team already know? If someone already knows say Spring leaver that knowledge and have them spread it about. Like wise with Guice or Pico.
If you want something really light weight you might want to have a look at fuse it's fairly extendable so might be what you're looking for.
cheers
N