Why use Spring framework when we can achieve loosely coupled code using interfaces? - spring

As far as i know we use spring IOC so that it becomes easy for developer to check the xml file to identify and control the flow of code by providing the dependencies explicitly.
But if we use autowire, developer actually has to check the code to identify which implementation is autowired to given class
same thing could have been achieved without actually using spring framework for example, so why we need spring or what is the real advantage of using springs in this case.
Interface Vehicle {
.....
}
Class Car implements Vehicle {
......
}
Class Example {
Vehicle v = new Car()
}
Or
Class Example {
#Autowire
Vehicle v;
....
}

This is a very good question!. Now for answer in the best way I consider that a little bit of story can be helps.
Spring was born in the EJB era in which all was configured in xml and Spring originally was a java framework for provide IOC POJO based. In this era was totally normal configure our application in xml and spring was a good choice because we can benefits of IOC without the EJB complexity and in a vendor free manner, EJB is not totally application server free because some times the vendor implementation especially for vendor specific configuration brings the application to do not totally portable, spring was a successful framework because was a solution for almost all the problems of an EJB application. Then the success of framework brings the framework to grow and include other capabilities like data access, web integration and more other integration and capabilities.
In this years also JavaEE grows and in JavaEE 6 was born CDI Spring provide a xml, annotation, java config groovy, kotlin dsl bean configuration in order to achieve flexibility and give a comfortable programming and configuration model, think about all the people that come from JabaEE 6+ that usually use #Inject for provide DI. Now said all this DI capability are to discretion of the developer.
In my opinion use #Autowired is dangerous because this brings you to Spring for ever and many issue of DI can arrives in case of more that one bean are configured. To enforce the effort of spring team to give you confort and free choice of configuration starting from Spring 4.3.x you can do a think like
interface Vehicle {
}
class Car implements Vehicle {
}
class Example {
private final Vehicle vehicle;
Example(Vehicle vehicle) {
this.vehicle = vehicle;
}
}
#Configuration
class Config{
#Bean
public Car car(){
return new Car();
}
#Bean
public Example example(Vehicle car){
return new Example(car);
}
}
#RestController
class Enpoint{
private final Example example;
Enpoint(Example example) {
this.example = example;
}
the your business code now is totally free from spring even the constructor on the rest controller do not required #Autowired annotation, of course you have configure it.
On the end I can say that you should use Spring not because Spring provide IOC, this can be achived in a Plain Java manner, whith Google Juice, Spring and many other IOC framework but I suggest you to use Spring for all the related project that give you many capabilities production ready like, Spring web for blocking IO, Spring WebFlux for no-blockin IO, Spring Integration for EIP, Spring batch for Enterprise ready Batch, Spring Cloud for Cloud native application and more and more, the power of Spring to day is the flexibility and completeness, of course, the law of spider man is valid! from great powers we have great responsibilities.
Spring give you many possibility but then is the developer responsibility to choose the best. Annotation give you speed especially during the prototyping but then is too rigid.
I hope that this long reflection give you an answer of your doubts

In this way, the problem is the Vehicle ā€œvā€ is coupled tightly to Car, every change of output generator may involve code change. If this code is scattered all over of your project, every change of the Vehicle will make you suffer seriously.

Related

Is it ok to use non-annotated classes (beans) in spring framework?

I have a spring-boot project. Some of the classes I am using it in the 'spring' way, meaning that they are annotated by "#Service", "#Repository", "#Autowired". At the same time, I have lots of classes, which are only used in the normal Java way, meaning that there are no any Spring annotations, and they are created in the standard way of constructing an object in a constructor.
For example, one of the non-annotated classes is:
public class GenericTree<T>
{
private GenericTreeNode<T> root;
public GenericTree ()
{
root = null;
}
public GenericTreeNode<T> getRoot ()
{
return this.root;
}
public void setRoot (GenericTreeNode<T> root)
{
this.root = root;
}
...
}
Is it OK or normal to have a mixure of classes with or without Spring annotations? Probably, I could convert all non-annotated classes into annotated classes by using Spring's annotation markers. Does that really benefit or is it necessary?
BTW, my application's main logic and functions are not web-centric, although they are created as a Spring project. The reason I created in Spring is I want to provide a restful service for my interface so that I can easily test in browser in development, and others can use it with Restful service.
Yes it is ok.
Keep in mind that annotations are not Spring exclusive. Annotations were introduced in Java 5 and they are just meta data for your Java code. This meta data can be useful at:
Compile time
Build time
Runtime
You can even create your own custom annotations and annotate your code with them.
Spring framework comes with some annotations and each one of them has its purpose, but that doesn't mean you have to annotate all your classes with Spring annotations when you are using this framework.
When you annotate your classes as Spring Beans, they become part of the Spring Application Context, thus making them available to be injected with the #Autowired annotation (Spring framework is based on the dependency injection design pattern). But Spring annotations have other implications too, I cannot go into the detail of each one of them but for example, you have to consider that the default scope of annotations like #Bean, #Component, #Controller, #Repository, #Service is Singleton. So whenever you annotate a class with one of these annotations and you don't define a scope, what you get is a singleton class shared all over your application. Other scopes are:
singleton
prototype
request
session
application
websocket
Taking in consideration your GenericTree class, does it make sense to annotate an abstract data structure class as a Spring Bean? Probably not.
So yes, when you develop an application based on Spring framework the normal thing is to have a mixture of Spring annotated classes and regular POJO's.
I recommend you to read the Spring framework documentation, learn what dependency injection is and the purpose and implications of the most used Spring annotations.

Injecting spring beans into legacy web app POJOs [duplicate]

This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 7 years ago.
In order to provide POJOs in my legacy web app (Tomcat 8.0.26) with the ability to send ActiveMQ messages I've taken the recommendation to introduce Camel (2.15.2) / Spring (4.2.1) into the app to purely for the purpose of managing pooled MQ connections. I'm hoping there isn't an easier way.
Doing things the Spring way I'm thinking everything would need to be based around an MVC architecture with HTTP servlet aware controllers having access to the servlet context and therefore the Spring context in order to inject beanFactory beans into classes annotated with #Controller and #Service (and in fact there must be a Spring #Controller class that enables Spring to inject the #Service class.
However, as I've stated this is legacy code that will not be using the spring web framework.
After much pain it seems that the only way I can get beanFactory beans injected into my POJOs is to go the AspectJ and Weaving route. Before I go down this road can someone tell me that this is currently the best approach (what I've read describing this solution is from 2011 Can't get Spring to inject my dependencies - Spring Newbie) ? Can you point me to documentation and a working example?
Many thanks.
1) aspectj with #Configurable
In your #Configuration annotated class/es
you can add some more annotations
#Configuration
#EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
#EnableSpringConfigured
#EnableAspectJAutoProxy
to enable aspectj and the #Configurable annotation,
you need to import the aspectj lib to your project and add the spring tomcat instrumentable java agent in your tomcat lib folder (give a look here, it exaplains how to configure tomcat) http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/instrument/classloading/tomcat/TomcatInstrumentableClassLoader.html
this is not going to help you if you are going to create your pojos using "new"
MyPojo p = new MyPojo(); // no black magic for this, you will need to satisfies the dependencies yourself) but that would be helpful for example when you load some entities through a framework like hibernate and you want to inject something into them.. #Configurable it's an option that can be evaluated in those cases, for what you describe I would rather not use it.
2) You can have some static methods that uses some static set spring-beans and use them from your pojos, something like
class Util{
private static SprintBeanWithJmsSupport x;
public static setSpringBeanToHandleJmsMessages(SprintBeanWithJmsSupport x){
Util.x = x;
}
public static sendJmsMessage(JmsMessage m){
x.sendMessage(m)
}
}
and you can go with Util.sendJmsMessage(...)
this is a bit shitty but it does the work, I don't personally like this approach
3) set your spring beans in your pojo when they need to use them (maybe behind some nice interfaces that suit your domain)
if you go with spring mvc you will likely end up having some controllers that will use some services (generally they handle security / db access and are the entry point to start the "use cases"), as everything wthin these layers is handled by spring it will be very simple to pass the spring-bean to handle jms messaging to your pojos, this seems to me quite a nice way to handle the problem
I went mostly based on memory and something may not be completely accurate, plus my english is .. what it is, so hope this can be helpful anyway.

Am I allowed to declare a lifecycle interceptor on an interceptor?

I have my business bean defined thus:
#Local
#Interceptors(BusinessInterceptor.class})
public class MyBean implements SomeBean { ... }
And then I want my BusinessInterceptor to be configured with Spring's SpringBeanAutowiringInterceptor:
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class BusinessInterceptor {
#Autowired
private SomeSpringBean someSpringBean;
}
Is this allowed/legal? I'm getting errors (NPEs, mostly) suggesting that the fields in BusinessInterceptor have not been initialized properly.
I doubt this can work. If I understand well your scenario, you have basically two DI containers, one is Spring and the other the app. server itself. Each one manages different elements. The BusinessInterceptor is created by the app. server which is unaware of Spring -- the #Autowired bean is then not set.
( Note that Spring and EJB3 have become quite similar now. You can have the same functionalities as EJB with Spring. Spring has indeed declarative transactions, dependency injection and AOP facilities similar to EJB3 interceptors (these are the main managed features). On the other hand, EJB3 is now so lightweight that there isn't really a compelling reason to use Spring with with EJB3. See Future of enterprise Java: full stack Spring or full stack Java EE. But this does not answer the question, and is just a little digression of mine :)

Should I use Spring or Guice for a Tomcat/Wicket/Hibernate project?

I'm building a new web application that uses Linux, Apache, Tomcat, Wicket, JPA/Hibernate, and MySQL. My primary need is Dependency Injection, which both Spring and Guice can do well. I think I need transaction support that would come with Spring and JTA but I'm not sure.
The site will probably have about 20 pages and I'm not expect huge traffic.
Should I use Spring or Guice?
Feel free to ask and followup questions and I'll do my best to update this.
If you like the "do-it-all-in-Java" philosophy that Wicket follows, then you might prefer Guice over Spring. There is no XML configuration in Guice - it is all done using the Guice Module class.
For example, your Wicket WebApplication class might look something like this:
public class SampleApplication extends WebApplication
{
#Override
protected void init()
{
addComponentInstantiationListener(
new GuiceComponentInjector(this, new GuiceModule()));
}
}
The GuiceComponentInjector comes from the wicket-guice extension. Here's the Module:
public class GuiceModule extends AbstractModule
{
#Override
protected void configure()
{
// Business object bindings go here.
bind(Greetings.class).to(GreetingRepository.class);
}
}
In this example, Greetings is an interface implemented by a concrete GreetingRepository class. When Guice needs to inject a Greetings object, it will satisfy the dependency with a GreetingRepository.
I have put together a sample project that demonstrates how to build a Wicket/Guice application for Google App Engine. You can safely ignore the App Engine specifics and focus on how the Wicket-Guice integration works.
If you do end up going with Guice, definitely check out Warp Persist for Hibernate, Guice Servlet for Tomcat, and wicket-guice for Wicket.
Spring would probably give you more flexibility, but if you just need DI then Guice may be a better choice.
It is difficult to answer as Spring has so many features that would make the DAO more flexible, and works well with Hibernate. It would help if you had more requirements for what you are looking for.
Here are a couple of comparisons between Spring and Guice and Spring, Guice and Picocontainer.
http://code.google.com/p/google-guice/wiki/SpringComparison
http://www.christianschenk.org/blog/comparison-between-guice-picocontainer-and-spring/
Don't forget CDI/JSR-299, part of Java EE 6. You can use weld-wicket to integrate wicket with CDI.
(as long as you're using the weld implementation (as GlassFish v3 and JBoss 6 do), but the weld-wicket is rather small so you could probably adapt it if needed).
I managed to get Wicket 1.4 + weld-wicket + wicket-contrib-javaee + EJB 3.1 + JPA 2.0 + wicket-security (SWARM) + Spring Security 3 + Spring 3 running together in a small proof of concept application. That's a bit too many frameworks though, will probably drop spring-security & spring as they appear redundant.

Managing complexity in a dependency-injected app with a large number of beans

I'm working on an Spring application which has a large number of beans - in the hundreds - and it's getting quite cumbersome to use and document.
I'm interested in any experience you have with DI-enabled apps with a large number of beans which would aid maintainability, documentation and general usage.
Although the application is Spring-based with a couple of context files, I'm open to listening about suggestions regarding any DI container and about DI in general as well.
You can use component scan and autowiring features to dramatically decrease the amount of Spring XML configuration.
Example:
<beans>
<!-- Scans service package looking for #Service annotated beans -->
<context:component-scan base-package="my.root.package.service"/>
</beans>
Your service classes must be annotated in order to be automatically scanned:
package my.root.package.service;
#Service("fooService")
public class FooServiceImpl implements FooService{
}
You can also use the #Autowired annotation to tell Spring how to inject the bean dependencies:
package my.root.package.service;
#Service("barService")
public class BarServiceImpl implements BarService{
//Foo service injected by Spring
#Autowired
private FooService fooService;
//...
}
I found the following to be of use:
split your Spring configurations into multiple standalone configurations, and use Spring's import facility to import configuration dependencies (see here, section 3.2.2.1). That way you have a set of configurations that you can combine or disassemble as required, and they are all self-dependent (all the dependencies will be explicit and referenced)
Use an IDE that is Spring-aware, and allows you to navigate through the configurations via point-n-click on beans (references/names, to-and-from source code). Intellij works very well at this (version 7 and beyond, I think). I suspect Eclipse would do something similar.
Revise what you're injecting where. You may want to refactor multiple bean injections into one composite or 'meta' bean, or a larger component. Or you may find that components you once thought you'd need to inject have never changed, or never demanded that injectability (for testing, implementing as strategies etc.)
I used to work with a huge Spring installation, with hundreds (thousands?) of beans. Splitting the configurations up made life a lot more manageable, and simplified testing/creating standalone processes etc. But I think the Intellij Spring integration that came with Intellij made the most difference. Having a Spring-aware IDE is a major timesaver.
As #Wilson Freitas says, use autowiring. I daily work with a system that has few thousand spring managed beans using mostly autowired. But I think the notion of "retaining the overall picture" is slightly misplaced. As a system grows you can't expect to do that in the same way as you did on a smaller system. Using #Autowiring forces you to use stronger typing than xml-based spring, which again means you can use the dependency tracking features of your IDE to navigate in dependencies.
I really think it's suboptimal to think that you need to understand too much of the "full" picture when it comes to the spring configuration. You should be focusing on your code and it's dependencies. Managebility and maintainability are achieved by organizing this code well, naming things well and managing your coupling; all of the stuff that applies even if you're not using spring. Spring shouldn't change much, and with the approval of JSR-330, it may even seem like dependency injection will creep further "under the hood" of the runtime environment.
Our strategy is:
naming conventions, e.g.: fooService, fooDao, fooController;
property setters following these conventions;
autowiring by name (autowire="byName"); we had many problems with autowiring by type, especially on the controller layer

Resources