Spring vs EJB
App servers written to support the EJB standard can, in theory, be ported from one compliant Java EE app server to another. But that means staying away from any and all vendor-specific extensions that lock you in to one vendor.
Spring ports easily between app servers (e.g., WebLogic, Tomcat, JBOSS, etc.) because it doesn’t depend on them
Spring Boot offers an even better way to write applications without Java EE app servers. You can create an executable JAR and run it on a JVM.
The Spring framework sits on top of the application servers and service libraries. Service integration code (e.g. data access templates) resides in the framework and is exposed to the application developers. In contrast, the EJB 3 framework is integrated into the application server and the service integration code is encapsulated behind an interface. EJB 3 vendors can thus optimize the performance and developer experience by working at the application server level. For example, they can tie the JPA engine closely to JTA transaction management. Another example is clustering support which is transparent to EJB 3 developers
Spring vs J2EE
Strictly speaking, Spring is a framework while Java EE is a specification which is implemented by various softwares such as JBoss and Glassfish.
The greatest difference is that Spring is an actual library while JavaEE is an API that has to be implemented. Depending on the JAVA EE container you could find a full implementation (e.g. Glassfish), a partial implementation (e.g. Tomcat) a full implementation with extra sugar (e.g. JBoss and others).