I have been working on a few web applications and REST web services recently (Spring IoC/MVC/Data JPA etc). They usually follow the same pattern: Controller classes --> Service classes (which have several "utility"/business logic classes autowired) --> Spring Data Repositories.
Pretty much all of the classes above are Spring singletons. I feel like this makes the code and some functions within a class dirtier; for example, I can't have a state in a class, I need to pass a lot parameters between methods, and I don't really like having more than 1-2 parameters (although I know sometimes it is necessary).
I was wondering how this problem is overcome in the big (e.g. enterprise) kind of application.
Is it a common practice to use non-Spring managed classes in the Spring application? If so, how do you pass dependencies into it (the ones that would normally be autowired)? If I use constructor injection for example, then I need to autowire all necessary dependencies into the class that creates the object and I wanted to avoid that. Also, I don't really want to be messing with load time weaving etc. to autowire beans into non-Spring objects.
Is using prototype scoped beans a good solution? The only thing is that I need to use AOP's scoped proxies (or method injection etc) to make sure that I get a new instance for any bean that is autowired into a singleton in the first place. Is that a "clean" and reliable option (i.e., is it certain that there will be no concurrency type of issues)? Can I still autowire any singletons into those classes with no issues?
Does anyone that worked on a large system (and actually managed to keep the structure not "bloated" and clean) have any recommendations? Maybe there are some patterns I am not aware and could use?
Any help appreciated.
Spring is well designed, you must not worry about about IoC implementation of DI. The pattern that you have mentioned /Controller Layer -> Service Layer -> Data Access Layer/ is good in practice, and it is ok that these singleton objects does not have state because of rule of OOP: "Think about objects as service providers that does one thing well". Models can have state as JPA units for storing something in Database. Is not mandatory that in large systems you will have dirty code how you mentioned passing a lot of parameters, it just depends on your design decision that will need a deeper construction.
I think my understanding of spring beans is a bit off.
I was working on my project and I was thinking about this situation.
Say I have class Foo
class Foo(){
public void doSomething(Object a , Object b){ // input parameters does not matter actually.
//do something
}
}
If I am using this class in another class like :
class Scheduler{
....
#Autowired
private Foo foo;
someMethod(){
foo.doSomeThind(a,b);
}
....
}
In the above case Instead of Autowiring the Foo, I can make doSomeThing static and directly use Foo.doSomeThing(a,b)
I was just wondering if there any advantage of creating a bean or if there any disadvantage of using static methods like this?
If they are same, When should I go for spring bean and when should do I simply use a static method?
Static methods are ok for small utility functions. The limitation of static code is that you can't change it's behavior without changing code itself.
Spring, on the other hand, gives you flexibility.
IoC. Your classes don't know about the exact implementation of their dependencies, they just rely on the API defined by interface. All connections are specified in configuration, that can be different for production/test/other.
Power of metaprogramming. You can change the behavior of your methods by merely marking them (via annotations of in xml). Thus, you can wrap method in transactions, make it asynchronous or scheduled, add custom AOP interceptors, etc.
Spring can instrument your POJO method to make it an endpoint to remote web service/RPC.
http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/
Methods in Spring beans can benefit from dependency injection whereas static methods cannot. So, an ideal candidate for static method is the one that does things more or less independently and is not envisioned to ever need any other dependency (say a DAO or Service)
People use Spring not because of some narrow specific futures that cannot be replaced by static classes or DI or whatever. People use Spring because of a more abstracted features and ideas it provide out of the box.
Here is a nice quote from Someone`s blog:
Following are some of the major benefits offered by the Spring Framework:
Spring Enables POJO Programming. Spring enables programmers to develop enterprise-class applications using POJOs. With Spring, you are able to choose your own services and persistence framework. You program in POJOs and add enterprise services to them with configuration files. You build your program out of POJOs and configure it, and the rest is hidden from you.
Spring Provides Better Leverage. With Spring, more work can be done with each line of code. You code in a more fast way, and maintain less. There’s no transaction processing. Spring allows you to build configuration code to handle that. You don’t have to close the session to manage resources. You don’t have to do configuration on your own. Besides you are free to manage the exceptions at the most appropriate place not facing the necessity of managing them at this level as the exceptions are unchecked.
Dependency Injection Helps Testability. Spring greatly improves your testability through a design pattern called Dependency Injection (DI). DI lets you code a production dependency and a test dependency. Testing of a Spring based application is easy because all the related environment and dependent code is moved into the framework.
Inversion of Control Simplifies JDBC. JDBC applications are quite verbose and time-taking. What may help is a good abstraction layer. With Spring you can customize a default JDBC method with a query and an anonymous inner class to lessen much of the hard work.
Spring’s coherence. Spring is a combination of ideas into a coherent whole, along with an overall architectural vision to facilitate effective use, so it is much better to use Spring than create your own equivalent solution.
Basis on existing technologies. The spring framework is based on existing technologies like logging framework, ORM framework, Java EE, JDK timers, Quartz and other view related technologies.
During unit testing you have more flexibility using bean because you can easily mock your bean methods. However, that is not the same with static methods where you may have to resort to PowerMock (which I recommend you stay away from if you can).
It actually depends on the role of the component you are referring to: Is this feature:
An internal tooling: you can use static (you wouldn't wrap Math.abs or String.trim in a bean)
Or a module of the project: design it to be a bean/module-class (a DAO class is best modular to be able to change/mock it easily)
Globally, you should decide w.r.t your project design what are beans and what are not. I think many dev put too much stuff inside bean by default and forget that every bean is an public api that will be more difficult to maintain when refactoring (i.e. restrained visibility is a good thing).
In general, there are already several answers describing the advantages of using spring beans, so I won't develop on that. And also note that you don't need spring to use bean/module design. Then here are the main reasons not to use it:
type-safety: Spring bean are connected "only" at runtime. Not using it, you (can) get much more guaranties at compile time
It can be easier to track your code as there is no indirection due to IoC
You don't need the additional spring dependency/ies which get quite heavy
Obviously, the (3) is correct only if you don't use spring at all in your project/lib.
Also, The (1) and (2) really depend on how you code. And the most important is to have and maintain a clean, readable code. Spring provides a framework that forces you to follow some standard that many people like. I personally don't because of (1) and (2), but I have seen that in heterogeneous dev teams it is better to use it than nothing. So, if not using spring, you have to follow some strong coding guidelines.
Quick high level concept of my design..
CLI tool to create AWS EBS snapshots
CLI tool just calls Java class com.util.SnapshotUtil
com.util.Snapshot calls AWS Interfacing class com.aws.AWSAdapter
example usage from command line..
cli-tool create-snapshot.. calls java class eventually calling below method
SnapshotUtil.createSnapshot() // statically call AWSAdapter.createSnapshot();
Currently everything is static and outside of Spring.
Now I am wondering if AWSAdapter should not be static, and loaded by Spring, which would mean my SnapshotUtil would need to create the Adapter through ApplicationContext, I believe, as well as supplying it an XML with the Adapter bean info.
Originally I thought since this is a simple util to deal with ebs snapshots, I could ignore Spring, but the AWSAdapter could potentially be used by other means, however, not sure if being static would be a pro or a con.
The Adapter is designed to only deal with an EBS Snapshot, so its basically either creating / deleting / viewing snapshots by using an AmazonEC2Client instance. Even if a Spring managed class wanted to use this Adapter, my question is if it matters if it loads the Adapter through Spring or just statically call it.
edit in response to answer:
I started turning it into a bean and removed all static references, I gave it a method getInstance() which will load itself through applicationContext and return to caller after initializing other dependencies and configurations. When I call this from outside of spring, is that okay? it seems to be working, is it still considered 'injecting'? I am pretty sure its not injecting, since the caller is not spring managed, but I feel this may be hacky? As in, I am using a spring bean in non spring class, so im never spring managed, so I feel there is no reason to turn the utility into a bean. I am still going to do it because I understand the benefits.
One reason I 'have' to turn it into a bean, is that it uses another spring bean I need to handle authenticating, however I thought about it and I could easily just instantiate the other bean using the 'new' keyword.
Am I correct when I say I turned my class into a bean but it is not 'injected' to callers, at least when using the getInstance() method? if I use the getInstance method() in a spring bean, would there be any difference if I were to 'inject' the utility through spring configurations instead?
Generally, you should favor non-static over static. Regarding your specific example, you should go with Spring beans, because that gives you much more flexibility when you start extending your application/module with more complex features.
For example, very soon static-only classes will require some resources from other parts of the system (and we all know how DI helps here).
Or you will need to advise static invocations with some aspects (be it only simple ones as logging of each request, but think of the more complex cases like transactions). With Spring beans this is very simple to achieve and, very important, simple to add afterwards without a big re-engineering and re-testing.
Also, you will much easier integrate beans with other Spring APIs and frameworks that are already well integrated with Spring. For example, you will easy use your bean in an Apache Camel route.
These are just a few points that came to my mind, there are many more of them. But, as always, consider all the pros and cons and pick the right tool for the job.
Edited part of the question
"When I call this from outside of spring, is that okay?"
Yes, it's fine to obtain the bean instance from the Spring application context directly in a class that is not managed by Spring or when the bean name is not known until runtime. In my example with Apache Camel route, that's exactly what Camel does. :)
"Am I correct when I say I turned my class into a bean but it is not 'injected' to callers, at least when using the getInstance() method?"
Yes, it is still a bean with all of the bean's functionality (with other beans injected in it, with aspects around it, etc).
"If I use the getInstance method() in a spring bean, would there be any difference if I were to 'inject' the utility through spring configurations instead?"
Regarding this, you may take a look at this question and at the article written by Martin Fowler, which is also referenced from the question.
In my opinion, you should not do it, it is less readable and quite unnecessary. Injecting the resources as fields is a type safe and a clean mechanism for a class to declare its dependent resources.
Also, bean lookup may be costly if executed frequently. I experienced this on a project I worked on in the past. I don't know why, but it takes some time for Spring (at least the Spring version we used then) to look up and return the bean, and it is noticeable if executed in a loop.
I am using Spring Declarative Annotation based caching in my project .
applicationContext.xml
<cache:annotation-driven />
Currently, everything works perfectly using spring annotation based caching.
We use ehCache and ConcurrentHashMap based underline caching mechanism in development and local environment.
Now there is a requirement in project where I need to update the behavior of Spring cache framework with some specific business requirements.
I wonder if any one help me to figure it out how can I replace
<cache:annotation-driven />
this annotation with any spring class definition where I can customize the behavior?
Check out org.springframework.cache.annotation.EnableCaching.
Look at the comments in the source code.
It does the equivalent of the < cache:annotation-driven /> but in spring java config.
You will prolly need to override this class: org.springframework.cache.aspectj.AnnotationCacheAspect
Its responsible for wiring the advise in.
This answer lead me in the right direction. The thing that I found about the inner workings of the caching support from spring is that its not Dependency injected outside of the cacheManager and KeyGenerator implementations. I wanted to subclass/extend the CacheAspectSupport and found that this class is first extended by CacheInterceptor but then that class is created using new statements in a class ProxyCachingConfiguration. To be able to replace the one class/method would take replacing a whole list of classes which doesn't sound very spring friendly (admittedly i could be missing something).
What i was expecting from the replacement of the line was a fully listed out set of spring beans that composed all of the AOP pointcuts, advice/aspects, etc. that make up the caching support, but it seems like this is alål just statically created classes with tight coupling between each other.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
In a few large projects i have been working on lately it seems to become increasingly important to choose one or the other (XML or Annotation). As projects grow, consistency is very important for maintainability.
My questions are: what are the advantages of XML-based configuration over Annotation-based configuration and what are the advantages of Annotation-based configuration over XML-based configuration?
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. But that an interface is going to be injected as a SubtypeY instead of a SubtypeX should not be included in the class, because if now you wish to inject SubtypeX, you have to change your code, whereas you had an interface contract before anyways, so with XML, you would just need to change the XML mappings and it is fairly quick and painless to do so.
I haven't used JPA annotations, so I don't know how good they are, but I would argue that leaving the mapping of beans to the database in XML is also good, as the object shouldn't care where its information came from, it should just care what it can do with its information. But if you like JPA (I don't have any expirience with it), by all means, go for it.
In general:
If an annotation provides functionality and acts as a comment in and of itself, and doesn't tie the code down to some specific process in order to function normally without this annotation, then go for annotations. For example, a transactional method marked as being transactional does not kill its operating logic, and serves as a good code-level comment as well. Otherwise, this information is probably best expressed as XML, because although it will eventually affect how the code operates, it won't change the main functionality of the code, and hence doesn't belong in the source files.
There is a wider issue here, that of externalised vs inlined meta-data. If your object model is only ever going to persisted in one way, then inlined meta-data (i.e. annotations) are more compact and readable.
If, however, your object model was reused in different applications in such a way that each application wanted to persist the model in different ways, then externalising the meta-data (i.e. XML descriptors) becomes more appropriate.
Neither one is better, and so both are supported, although annotations are more fashionable. As a result, new hair-on-fire frameworks like JPA tend to put more emphasis on them. More mature APIs like native Hibernate offer both, because it's known that neither one is enough.
I always think about annotations as some kind of indicator of what a class is capable of, or how it interacts with others.
Spring XML configuration on the other hand to me is just that, configuration
For instance, information about the ip and port of a proxy, is definetly going into an XML file, it is the runtime configuration.
Using #Autowire,#Element to indicate the framework what to do with the class is good use of annotations.
Putting the URL into the #Webservice annotation is bad style.
But this is just my opinion.
The line between interaction and configuration is not always clear.
I've been using Spring for a few years now and the amount of XML that was required was definitely getting tedious. Between the new XML schemas and annotation support in Spring 2.5 I usually do these things:
Using "component-scan" to autoload classes which use #Repository, #Service or #Component. I usually give every bean a name and then wire them together using #Resource. I find that this plumbing doesn't change very often so annotations make sense.
Using the "aop" namespace for all AOP. This really works great. I still use it for transactions too because putting #Transactional all over the place is kind of a drag. You can create named pointcuts for methods on any service or repository and very quickly apply the advice.
I use LocalContainerEntityManagerFactoryBean along with HibernateJpaVendorAdapter to configure Hibernate. This lets Hibernate easily auto-discover #Entity classes on the classpath. Then I create a named SessionFactory bean using "factory-bean" and "factory-method" referring to the LCEMFB.
An important part in using an annotation-only approach is that the concept of a "bean name" more or less goes away (becomes insignificant).
The "bean names" in Spring form an additional level of abstraction over the implementing classes. With XML beans are defined and referenced relative to their bean name. With annotations they are referenced by their class/interface. (Although the bean name exists, you do not need to know it)
I strongly believe that getting rid of superfluous abstractions simplifies systems and improves productivity. For large projects I think the gains by getting rid of XML can be substantial.
It depends on what everything you want to configure, because there are some options that cannot be configured with anotations. If we see it from the side of annotations:
plus: annotations are less talky
minus: annotations are less visible
It's up to you what is more important...
In general I would recommend to choose one way and use it all over some closed part of product...
(with some exceptions: eg if you choose XML based configurations, it's ok to use #Autowire annotation. It's mixing, but this one helps both readability and maintainability)
I think that visibility is a big win with an XML based approach. I find that the XML isn't really that bad, given the various tools out there for navigating XML documents (i.e. Visual Studio + ReSharper's File Structure window).
You can certainly take a mixed approach, but that seems dangerous to me if only because, potentially, it would make it difficult for new developers on a project to figure out where different objects are configured or mapped.
I don't know; in the end XML Hell doesn't seem all that bad to me.
There are other aspect to compare like refactoring and other code changes. when using XML it takes serous effort to make refactoring because you have to take care of all the XML content. But it is easy when using Annotations.
My preferred way is the Java based configuration without (or minimal) annotations. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java
I might be wrong, but I thought Annotations (as in Java's #Tag and C#'s [Attribute]) were a compile-time option, and XML was a run-time option. That to me says the are not equivalent and have different pros and cons.
I also think a mix is the best thing, but it also depends on the type of configuration parameters.
I'm working on a Seam project which also uses Spring and I usually deploy it to different development and test servers. So I have split:
Server specific configuration (Like absolute paths to resources on server): Spring XML file
Injecting beans as members of other beans (or reusing a Spring XML defined value in many beans): Annotations
The key difference is that you don't have to recompile the code for all changing server-specific configurations, just edit the xml file.
There's also the advantage that some configuration changes can be done by team members who don't understand all the code involved.
In the scope of DI container, I consider annotation based DI is abusing the use of Java annotation. By saying that, I don't recommend to use it widely in your project. If your project does really needs the power of DI container, I would recommend to use Spring IoC with Xml based configuration option.
If it is just for a sake of Unit-test, developers should apply Dependency Inject pattern in their coding and take advantages from mocking tools such as EasyMock or JMock to circumvent dependencies.
You should try to avoid using DI container in its wrong context.
Configuration information that is always going to be linked to a specific Java component (class, method, or field) is a good candidate to be represented by annotations. Annotations work especially well in this case when the configuration is core to the purpose of the code. Because of the limitations on annotations, it's also best when each component can only ever have one configuration. If you need to deal with multiple configurations, especially ones that are conditional on anything outside the Java class containing an annotation, annotations may create more problems than they solve. Finally, annotations cannot be modified without recompiling the Java source code, so anything that needs to be reconfigurable at run time can't use annotations.
Please refer following links. They might be useful too.
Annotations vs XML, advantages and disadvantages
http://www.ibm.com/developerworks/library/j-cwt08025/
This is the classic 'Configuration versus Convention' question. Personal taste dictates the answer in most cases. However, personally I prefer Configuration (i.e. XML based) over Convention. IMO IDE's are sufficiently robust enough to overcome some of the XML hell people often associate w/ the building and maintaining an XML based approach. In the end, I find the benefits of Configuration (such as building utilities to build, maintain and deploy the XML config file) outweighs Convention in the long run.
I use both. Mostly XML, but when I have a bunch of beans that inherit from a common class and have common properties, I use annotations for those, in the superclass, so I don't have to set the same properties for each bean. Because I'm a bit of a control freak, I use #Resource(name="referredBean") instead of just autowiring stuff (and save myself a lot of trouble if I ever need another bean of the same class as the original referredBean).
There are some pros and cons of annotation configuration from my experience:
When it comes to JPA configuration since it is done once and usually are not changed quite often I prefer to stick to annotation configuration. There maybe a concern regarding possibility to see a bigger picture of configuration - in this case I use MSQLWorkbench diagrams.
Xml configuration is very good to get a bigger picture of application but it maybe cumbersome to find some errors until runtime. In this case Spring #Configuration annotation sounds as a better choice since it let you see a bigger picture as well and also allows to validate configuration on compile time.
As for Spring configuration I prefer to combine both approaches: use #Configuration annotation with Services and Query interfaces and xml configuration for dataSource and spring configuration stuff like context:component-scan base-package="..."
But xml configuration bits java annotations when it comes to flow configuration(Spring Web Flow or Lexaden Web Flow) since it is extremely important to see a bigger picture of the whole business process. And it sounds cumbersome to have it implemented with annotations approach.
I prefer combining both approaches - java annotations and essential xml minimum that minimize configuration hell.
For Spring Framework I like the idea of being able to use the #Component annotation and setting the "component-scan" option so that Spring can find my java beans so that I do not have to define all of my beans in XML, nor in JavaConfig. For example, for stateless singleton java beans that simply need to be wired up to other classes (via an interface ideally) this approach works very well. In general, for Spring beans I have for the most part moved away from Spring XML DSL for defining beans, and now favor the use of JavaConfig and Spring Annotations because you get some compile time checking of your configuration and some refactoring support that you don't get with Spring XML configuration. I do mix the two in certain rare cases where I've found that JavaConfig/Annotations can't do what is available using XML configuration.
For Hibernate ORM (haven't used JPA yet) I still prefer the XML mapping files because annotations in domain model classes to some degree violates The Clean Architecture which is a layering architectural style I have adopted over the past few years. The violation occurs because it requires the Core Layer to depend on persistence related things such as Hibernate or JPA libraries and it makes the domain model POJOs a bit less persistence ignorant. In fact the Core Layer is not supposed to depend on any other infrastructure at all.
However, if The Clean Architecture is not your "cup of tea" then I can see there are definitely advantages (such as convenience and maintainability) of using Hibernate/JPA annotations in domain model classes over separate XML mapping files.