As a relatively new comer to the Spring world, I figured it would be nice to have a community Wiki page that lists common pitfalls in Spring-based projects.
These include:
Misunderstood concepts
Popular features from Spring 2.X that are no longer recommeded in Spring 3.X
Abused features
Performance killers
Most abused and misunderstood concept: Not everything need to be injected.
Others:
Performance problems when using lots of AOP request scoped beans (perf)
Singleton beans are loaded differently in BeanFactory and ApplicationContext. A bean factory lazily loads all beans, deferring bean creation until the getBean() method is called. An application context loads all singleton beans upon context startup.
Unified property management through Spring's new Environment abstraction in 3.1 rather than using PropertyPlaceholderConfigurer
Other deprecated features
Mixing Annotation-based configuration with XML-based configuration. Happens to me all the time...
Calling public methods using this when inside a proxy-enriched bean. This is a recurring problem in StackOverflow, explained here.
Injecting bean with prototype scope does not mean you'll have a new instance every time you use this bean. Explain lookup-method. Also: how to use session-scoped beans in singletons.
Spring can be used outside of the web container. Example of ClassPathXmlApplicationContext.
Proper usage of Spring testing support. Explain default transaction behavior.
I'll start first. Use of DAO templates, such as JpaDaoSupport and JpaTemplate for JPA, is no longer recommended in Spring 3 in favour of direct use of JPA.
Related
I'm trying to understand what Spring AOP is and how it works. The questions I can't answer are the following:
One of the reasons why Spring AOP is not used compared to AspectJ is that Spring AOP cannot add an aspect to anything that is not created by the Spring factory. What does this mean? Isn't everything created from the Spring Factory?
How does Spring Core use the Spring AOP module "behind the scenes"?
What is meant by "Spring AOP is proxy-based"?
One of the reasons why Spring AOP is not used compared to AspectJ is
that Spring AOP cannot add an aspect to anything that is not created
by the Spring factory. What does this mean? Isn't everything created
from the Spring Factory?
In short, that Spring builds proxies for the beans in the Container, and relyies on these proxies to implement AOP.
Regarding the comparison with AspectJ:
From the Spring.io reference docs:
"
...
Thus, for example, the Spring Framework’s AOP functionality is normally used in conjunction with the Spring IoC container. Aspects are configured by using normal bean definition syntax (although this allows powerful “auto-proxying” capabilities). This is a crucial difference from other AOP implementations. You cannot do some things easily or efficiently with Spring AOP, such as advise very fine-grained objects (typically, domain objects). AspectJ is the best choice in such cases. However, our experience is that Spring AOP provides an excellent solution to most problems in enterprise Java applications that are amenable to AOP.
Spring AOP never strives to compete with AspectJ to provide a comprehensive AOP solution. We believe that both proxy-based frameworks such as Spring AOP and full-blown frameworks such as AspectJ are valuable and that they are complementary, rather than in competition. Spring seamlessly integrates Spring AOP and IoC with AspectJ, to enable all uses of AOP within a consistent Spring-based application architecture. This integration does not affect the Spring AOP API or the AOP Alliance API. Spring AOP remains backward-compatible. See the following chapter for a discussion of the Spring AOP APIs."
What is meant by "Spring AOP is proxy-based"?
How does Spring Core use the Spring AOP module "behind the scenes"?
Proxy based means that, beans are wrapped in another object (the proxy) which itercepts the calls to the obejct and can act upon that interception before calling the real method on the wrapped oject.
There are two ways of implementing this, one is using java Dynamic Proxys (Reflection), the other is using CGLIB, a library that adds the proxy capability at bytecode level.
Spring.io reference docs AOP
An article about Proxys
You should read this for comparison https://stackoverflow.com/questions/1606559/spring-aop-vs-aspectj&ved=2ahUKEwim6cD24-DoAhVMzaQKHd4SDfMQFjAMegQICRAB&usg=AOvVaw1Sps_B0sPQPKRD5N9UtOpA&cshid=1586622128032
In our web application, we are using Spring as dependency injection mechanism. We have multiple DAOs and Manager spring beans which has a default scope of singleton.We have made sure that all of these beans are stateless. I have read at multiple places why singleton pattern is bad : What is so bad about singletons? .Forgive me if this is asked already but please answer if the above mentioned design comes under bad coding practice and also how improvements can be made to same.
As you can see in the first response to the link you posted (what is so bad about singleton) three problems of singleton are:
Hide dependencies of the application in the code
Violation of single responsible principle
Code strong coupled
None of them is present if you use the singleton via spring dependency injection, because:
Dependencies are stored in the configuration file, not in the code
The single responsible principle is not broken because the construction of your dao is handled by the spring engine, not by your dao
Code is not strong coupled because the configuration can be changed without changing the code
So yes using spring singletons can be a very nice solution not having problems of real singletons.
Spring singleton beans are not using the singleton pattern. They just happen to be instantiated once by the framework, and injected into every component that needs them.
The singleton pattern is considered an anti-pattern mainly because it makes all the classes relying on it hard to test. Spring singleton beans don't have this problem at all.
The primary disadvantage of singletons is that they tend to cause entanglements between different client classes if they have any state. Well-designed service classes should not have any operation-specific state (they'll usually have something like a reference to a database pool or other resources, injected at instantiation and then not changed after), and it's perfectly fine to use a singleton-scoped bean for such services.
If you read the answers from the question you've linked, they don't really apply to Spring singletons. When using Spring beans in singleton scope they're not hard to test, they do not control their own creation, and they are accessed through an interface (or at least should be!).
Google App Engine frontend instances are dynamically scaled. That means App Engine automatically creates new instances when load increases and turns off instances when they are not being used. Reloading instances may result in additional latency for users. Frontend instances also have a 60 seconds deadline to complete a given request.
As I am using Spring MVC and Spring IOC in my GAE application, to Optimize Spring Framework usage, I have gone through Best Practices for App Engine Applications.
In that link I am completely confused with the section Reducing or Avoiding the Use of Relationship Autowiring . It says automatic wiring can significantly the time required to resolve the beans during application initialization time, so they suggest autowire byName instead of using autowire byType .
So my question is How autowire byName reduces bean resolving time ?? . And also I would like to know is there any better way to inject beans ?. Is there any best practices for Spring IOC to reduce application initialization time.
Autowire "byType" obviously have to use some mechanism (and some processing )to correctly identify the bean whereas using "byName" provide a direct identification.
Take an analogy of a group of many breed of cats and dogs. To find the terrier out of the group you will have to first identify all breeds however when you use name of dogs it is much easier and improve the identification.
Spring does scanning of the classes for annotations which are inside package defined in "context:component-scan" if there are many classes in package it will take a while during start-up of an application hence it is suggested to use autowire byName.
Let me give a reply to all the answers
So my question is How autowire byName reduces bean resolving time ??
already explained by apurvc, in particular if you use interface or you use massive class inheritance Spring will have to inspect the hierarchy of classes
I would like to know is there any better way to inject beans ?
Yes, do not inject bean by autowire but use set or get property, as
you can; I use this policy.
Avoid autoscan component
Use singleton or bean pools or factory to reuse or construct object
Is there any best practices for Spring IOC to reduce application
initialization time.
use lazy initialization (#Lazy annotation)
put not dependent bean at the top of XML definition
But you do not really need these solutions if you are JEE developer.
I have understood that if I use EJB in Spring context, I get all the same benefits as if I was using it in "pure" EJB3 environment, is this true? I have googled but can't find a definitive, clear answer.
For example, let's say I have a session bean that updates some tables in the database and it throws a System Exception. In "pure" EJB3 environment the transaction is rolled back. What if I for example #Autowire this bean using Spring, does Spring take care of the transaction handling same way as does the EJB3 container? Or what? Does it maybe require some specific configuration or is it fully "automatic"?
I have understood that if I use EJB in
Spring context, I get all the same
benefits as if I was using it in
"pure" EJB3 environment, is this true?
You usually use either POJO + Spring or EJB3. I'm a bit confused by what you mean by "EJB in Spring"...
POJO + Spring and EJB3 are quite close now, and have the same facilities when it comes to declarative transaction management.
I don't know all the details about security, but I would say that both technologies are also very similar.
Actually both Spring and EJB3 rely on other specifications. The important ones are: JPA (persistence), JTA (distributed transaction), JMS (messaging), JDBC (data sources). Good support for that exist in the two technology stacks.
Both technologies have become very flexible and you can choose what to use or not. So you can have EJB3 in an app. server and be very light. Or you can use Spring with all modules which is almost as heavy as a full-fledged app. server.
I think the EJB3 model is still a bit richer, with things like remoting, stateful session beans (SFSB), container-managed transactions, and extended persistence context. Plus the possible support of clustering depending on the app. server. But these are advanced features which are use seldom (and IMO require expertise).
See EJB3 vs Spring
spring has many features, one of which is transaction management, which uses a common abstraction accross all different orm implementations (jpa, raw hibernate, jdbc, jdo etc). The default behavior is that in a transactional method, a runtime exception causes a rollback (which is probably what you want), but you can also fine-tune the rollback rules.
However, none of this requires EJB. If you don't use EJBs (stateless, stateful, mdbs), JPA will be enough for that, and the spring jpa support is excellent. In 90% of the cases spring will provide everything you need without EJBs.
EDIT:
read this about Spring EJB integration
You can have Spring handle transactions and roll back accordingly. You have to configure it to do so, but that's also true of EJBs.
Nothing in life is truly "automatic". You have to tell the code what you want sometime.
The real question is: Why do you think you need both EJBs and Spring? Anything you can do with EJBs can be done using POJOs with Spring. What are EJBs buying you here?
I got very good answers with links to articles, and from those I compiled my understanding that yes, the session beans work the same way regardless of if they are used with Spring or without, as long as the beans are defined in the Spring context with <jee:jndi-lookup>. Also found a good, simple article about this: http://java.dzone.com/articles/ejb-30-and-spring-25
However I can't accept just one answer because to me they are all equally good, but none of them exactly in point :) Could be that my question was not clear enough to start with...
(It was suggested that I post this as an answer to my own question)
I've recently started learning the Spring Framework, and I'm a bit unclear on how the ApplicationContext is supposed to be used - in both standalone and web applications. I understand that the ApplicationContext, once instantiated with the spring configuration xml, is the "spring container" and is a singleton.
But:
In the starting point - main method - of an app do I use ApplicationContext.getBean("className") and then rely on DI for all other registered beans or is there a way to use only DI?
Is there any other place besides the main method where I could/should use ApplicationContext.getBean("className")?
If and when should ApplicationContext.getBean("className") be used in a web app?
If in your opinion there is information I MUST know regarding DI related to web applications, even though I may not of specifically inquired about it, please share.
You need at least one call into the context from outside it, there's no avoiding that. With webapps, that part is hidden from you, and it it feels like everything is using DI, even though Spring's servlet glue code is doing some unpleasantness behind the scenes.
Could, yes; should, no. There are very few good reasons for calling getBean yourself.
The most obvious scenario is when you have a servlet filter that needs access to the context. FIlters aren't managed by Spring, and so cannot have stuff wired into them by Spring.
That's a bit too vague. Read the reference docs :)
I generally recommend only one usage of ApplicationContext.getBean() per application, and rely on the Spring configs to do the rest.
The exception applies in unit tests, where I want to load up a particular subset of beans (so I would explicitly load a bean that normally would be loaded from the top of my bean hierarchy).