Selecting the right candidates for spring bean. What to what not to - spring

Last year when I started learning spring I remember an article that expalined that not all pojos are to be defined as beans. So I'm planning to create a web app say EmployeeMaintenance. CRUD Functionalities are there. I will surely end up creating pojos like Employee , EmployeeSupplementaryDetails, Address etc. Should I makes these beans and configure them in xml or annotate whatever. I'm sure my understanding of bean is not enough. I know that Dbconn , services etc should definitely be declared as bean.
All I need is what are the parameters I should consider before I make a pojo a Spring Bean.

General rule for making Java class a Spring bean is to ask yourself if you need to inject object into some other object or if you want the object to be managed by Spring components. The classes you listed as example doesn't seem to be good candidates for being Spring beans - they represent model data and will be passed as some service's methods parameters.
Examples of typical CRUD application beans:
EmployeeService (you would want to inject it to controller or other service)
EmployeeRepository / EmployeeDao
EmployeeController (it will be bean managed by Spring's MVC framework)
etc.
Spring beans are building blocks of your application. Let's suppose you need to create web application for storing and managing employees records (creating, retrieving, updating, deleting). What you will need is web controller that will handle incoming requests for several operations (EmployeeController). Good practice is that controller doesn't implement any business logic - all it should do is to delegate work to service beans. So you would need bean like EmployeeService. Then controller would ask service to do some work (give me employees list / remove John Smith from database / change salary for Ann Jackson / etc). So service will be controller's dependency (service is injected into controller). Service can also have some dependencies (like repository object, which is responsible for handling communication with data storage) and these dependencies would be injected to service. Dependency management is Spring's core feature.
Good practice in object oriented programming is to have small classes that are responsible for doing one kind of actions. Such objects are much easier to test and understand. The more classes you have, the building application from blocks is harder, so it's worth to delegate it to framework like Spring. Without Spring you would need to create controller class, then inside of it create service, then inside of it create other dependencies and so on. Spring does it for you, so all you need to do is to declare dependencies and they will be injected automatically. If you want to replace implementation of your service with another (for example repository that used XML file for storing data with repository storing data in relational database) then you just have to change your bean definition.
Regarding to beans managed by Spring, typical example is database transaction manager (eg. org.springframework.orm.jpa.JpaTransactionManager). If you define such bean, and declare which methods should be transactional, then Spring will take care of transactions management (will open, commit or rollback transactions automatically).

Related

Standard Scope for Spring classes

In a spring MVC app , by default all beans are singleton ,but what should be the standard scopes for below classes according to good programming practices:
1.DAO classes
2.Controller classes
3.DTO classes
4.Service classes
I have read that DAO and Controller classes should be singleton scoped and DTO classes should not be beans so not annotated, whenever required, DTO classes should be instantiated using "new".
What will be the scope of #Service classes ?
And Which classes will have the Request and Session scopes if none of the above classes are created in these 2 scopes?
First of all not classes, but Spring managed beans have a scope. Difference is that you can have classes in your application that you didn't configure to be managed by Spring (So for example you didn't provide #Component annotation)
For the Spring managed beans default scope is Singleton. That means Spring container will provide the same instance everytime you ask for that bean to be autowired.
You can change that default scope with for example #Scopeannotation. So to answer your question, all of the above mentioned choices would have default scope of singleton but you could changed that to be requestor sessionscope if you would like (only applicable in web applications though). You can read more about setting scopes here.
ps. DTO classes are usually not declared to be managed by Spring - letting Spring manage a simple data transfer object doesn't make much sense.
So basically two things to consider here. The 1st is that if a bean is required to be declared as a spring bean . It depends on if you need to use the spring features for this class such as #Transactional , #Async , #PreAuthorize , #Autowired (i.e dependency injection) , or ensure the bean has certain scope etc. If not , it is simpler not define it as a spring bean and simply create it by yourself.
So the following types of the classes are required to define them as spring bean in most cases:
DAO because most probably need to inject EntityManager or JdbcTemplate to it
Controller because it is a part of spring-mvc and you need to define it as a bean such that you can use #RequestMapping / #GetMapping / #PostMapping / #PutMapping / #DeletMapping / #PatchMapping etc. on its method.
Service class because you need to inject it into the controller and you need to use #Transactional to manage the DB transaction for its method.
For DTO , in most case you can create it by yourself since it is just a data container in nature and does not require to use any spring features.
The 2nd thing to consider is what scope does a bean should be. You mainly need to think about if an instance of that class is okay to be executed safely by multiple request (i.e thread) concurrently. If yes , you can simply use the default singleton scope. If not , you can think about if you want each HTTP request (i.e #RequestScope) or each HTTP session (i.e. #SessionScope) has their own instance of that class to work with. For example , if you are implementing some shopping cart , you most probably want that the HTTP session has their won instance of a shopping cart and so you should use #SessionScope for the shopping cart.

Issue in understanding the Spring Bean Scopes Vs Spring web flow Session Scopes

We Know the Spring Framework gives
singleton,
prototype,
request,
session,
global_session
bean Scopes.
Also we know that Spring web flow gives flowScope,viewScope,requestScope,flashScope,conversationScope.
So If i mentioned one Component, say Student, as #Component #Scope=singleton in a spring MVC project. For each request, will it create a new Student Object or Spring container will create only once?
You are confusing yourself with objects and beans.
For each request, will it create a new Student Object or Spring container will create only once?
The functioning of Spring is purely using beans. When you declare a something like a #Component, it's just an annotation that tells Spring that the part you've declared as a component is either Model or View or Controller i.e. a component of MVC. When you say something like #Scope=singleton, it tells Spring that only a single object instance can access the bean.
Let me make it more clear. Say you and I are objects and a strawberry candy is a bean. So if you have the candy. I cannot take it from you. Meaning only one of us can have that candy. It's the same thing with singleton scope.
Hope I made things simpler.. :)

In-memory structure in Spring

I'm a Spring novice user.
I have a database table which is static in nature and contains only a few records.I want a Map-like structure(id - name) that holds two columns of this table. This Map must be loaded/initialized when the web application is started and must be applicable throughout the application's context, independent of the users sessions and must be read-only. This way, I can save a lot of DB queries as the different operations will simply read from this Map.
While I'm aware of ServletContextListener etc. of Java EE, I don't know how to achieve the same in Spring. Is a Spring Service bean the right place/way to initialize and store such a Map?
Please guide me about the same.
You can create a regular spring bean exposing a method which loads the data you require from the database and stores it in your map. Annotate this method with #PostConstruct and spring will ensure that it is called when your application context starts, hence loading your map.
You could use springs JdbcTemplate to load your data within this method
See Spring PostConstruct doco for information on the #PostConstruct annotation
See JdbcTemplate doco for information on JdbcTemplate
You can configure lists, sets and maps in a Spring XML configuration. See here for more examples.

Scenario when we may be needing #Configurable in spring?

I have question about the need of using #configurable. I have gone through the blog that explains how to use #configurable. But the question that comes to my mind is, what can be the scenario when we need to use #configurable. I can think of two scenarios where it can be useful
In a legacy project, when we are already making any bean with new operator and we want to make it spring managed.
In a new project, we want to enforce that even if developer makes the bean with new operator, still it is spring managed.
Otherwise for new beans we can always declare them in applicationContext.xml and I do not see any need to declare them #configurable.
Please let me know if above understanding is correct or if I am missing something.
UPDATE:- Basically as per my understanding configurable is generally used to inject dependency when creating the object with new operator. But why would i be creating the object with new operator when i am using spring
#Configurable annotation is meant for injecting dependencies in domain-driven applications. That means, in such applications, the domain objects interact with each other to perform a certain operation.
Take the following example:
In an invoicing application, the Invoice class provides a constructor to create it, then it has methods to validate, and finally persist it. Now, to persist the invoice, you need a DAO implementation available within the invoice. This is a dependency you would like to be injected or located. With Spring's #Configurable, whenever an invoice is created using the new operator, the appropriate DAO implementation will get injected and can be used for all persist operations.
I had a more realtime scenario where I used #Configurable annotation as described here.

Spring MVC with JSF 2, is this the only way?

All the examples I've seen so far integrating spring/mvc with JSF uses DAO class, DAOImp, Service, ServiceImp and then JSF ManagedBean and as far as I know with EJB 3.1 all I need is EJB and JSF ManagedBean. I am not mentioning entities. So based on my understanding with Spring + JSF I need:
5 classes and with EJB + JSF I need only two classes. Please correct me if am wrong but if am right then what's the advantage of using spring with JSF.
Thanks.
You are wrong. -- You can skipp the DAO, DAOImpl and ServiceImpl if you want to implment all in the Service Class.
But even in EJB it is best practice to seperate the Service and the DAOs.
The usage of Interfaces is a kind of style. If you use interfaces, at least you can skip them to and create your services (and Dao) like EJB 3.1 interface free Beans (I don't know the correct name at the moment). At least there are the same pro and cons to use interfaces in Spring and EJB 3.1.
Summary: You can build Spring JSF2 Apps with 2 classes to, but it is best practice to seperate at least JSP (view), Service (EJB's) and DAOs.
comment by Spring or JSF: Ralph please give me an example, suppose I've an entity: Person with id, firstName and lastName what would be the code I need from spring aspect?
In traditonal Spring architecure you have the:
Person (Entity) Class -- the one with the #Entity
PersonDao - Interface that provides data base Load, Strore, Delete and Find Methods for the Person
PersonDaoImpl - implementation of the PersonDao Interface - (#Repository)
PersonService - Interface that provides business functionality arround the person, for example a create method that send an email after a person is created
PersonServiceImpl - Implementation of the PersonService Interface - it uses for example the PersonDao and other Sevices to provides its functionality (#Service)
PersonJSF-Managed Bean - handles the JSF stuff but has no business functionality, it uses the PersonService (or an other Service) to start business functionality
This is one of the most common architecural style (not only in Spring). But even for this there are some variants:
how DAO's can be invoked? All Dao Functions must be invoked via the according Service -- or direct
DAOs with or whithout Interfaces? (may you need the Interfaces for your Test Mock Framework?) -- (have a look at Hades, there is only the Interface, but in most cases no Impl)
Services with or whithout Interfaces? (
...
BTW: one other very intresting architural style, is the one hat Spring ROO uses: It has only the View (PersonController) and the Model (Person), and all DAO and Service Functionality is put in the Model class. -- That is a bit of real OO Design.

Resources