How to set up the code for Spring + Hibernate dependency injection? - java

I've a newb to Java coming from C++ / C#.
My project is currently set up like this:
org.blah.config
HibernateConfig.java
org.blah.customer
Customer.java
CustomerController.java
CustomerService.java
HibernateConfig sets up the hibernate stuff and exposes the LocalSessionFactoryBean bean.
CustomerController is the REST entry point, it doesn't really have much logic, it sort of just wraps the CustomerService.java (or should I call it CustomerRepository?).
CustomerService.java (or CustomerRepository?) wraps the DB stuff. This is where I have:
#Autowired
private SessionFactory sessionFactory;
In my CustomerController, if I do:
private CustomerService customerService = new CustomerService();
it doesn't inject the sessionFactory.
From some samples I've found, people seem to create a CustomerService bean inside of HibernateConfig and then inject that into the constructor of the controller. Is that a good practice? Would I then rename my HibernateConfig to something more specific like CustomerHibernateConfig, etc.
Just trying to get an understanding of how/where to put the config & create the service / repo instance so it can be injected into the controller.

This is quite a hard question to answer in a few words. You are asking for a whole architecture that will depend a lot on the chosen design pattern, but considering you have controllers and services, let me put it this way. MVS is just a simplification and it's not a perfect approach. This will raise so many more questions like.
How much logic should go into a controller?
Should a model contain any logic?
Should a view contain logic?
Questions like these are very hard to answer, since these are very subjective. Still, I have been using Spring for a while and will give you my advise.
The controller's function is to validate inputs and a redirect to views when needed or to respond to clients' requests. If you got domain logic (aka business logic, business rules, and domain knowledge), the logic that makes business-critical decisions, then it shouldn't be on the controller, it should be on the services.
Now, I would say that you are missing a layer on your architecture, I would definitely add a DAO, which is a design pattern that defines a way to decouple the persistence layer of your application. Which is what you would understand as a Repository.
With that said, you only need one HibernateConfiguration and do the corresponding mappings in each model or XML file related to that model. I would advise to use annotations instead of XML files.
If you want to learn how to implement a Spring project that uses Hibernate, you can see how easy it is by following this Baeldung's tutorial. That page does have the best guides regarding the usage of Spring.

Related

DI in Java without annotations?

Is there any way (existing framework) to configure DI in Java without having to add annotations to classes where they "don't belong"?
In my research, it looks like to accomplish constructor injection we need to add some annotation to the constructor, like this:
#Inject // or #Autowired for Spring Boot
public MyInjectedClass(IThing1 thing1, IThing2 thing2) { ... }
Spring Boot also suggests adding #Service to implementations in order to register them with DI for injection.
Adding these annotations brings DI into the injected class (MyInjectedClass and any controllers, service implementations, etc.). Those classes should have no concept of DI, they should just be given the things they ask for in the constructor and not care about how they got there.
I know you can use the #Configuration attribute in Spring Boot, but this still feels not very configurable or powerful. Is there any way to accomplish this using Java without annotations? E.g. like how SimpleInjector, AutoFac, etc. work in C#? (Configured via code, not XML or config files, and not via annotations.)
If not, I'm curious why such a different approach has been taken between Java and C# in regard to DI.
Update I've offended someone in the comments but that was not my intent at all. I am asking a legitimate question. Let me highlight my concern/question in another way.
Suppose I have the following packages/classes. I have marked each case where each type of DI will appear. By "appear" I mean these marked classes/packages have some relation to the DI framework being used.
[A]: annotation-based DI (3rd party package dependency)
[C]: configuration-based DI
data_access [A]
repositories
PersonRepository [A]
logic [A]
people
CreatePersonCommandHandler [A]
UpdatePersonCommandHandler [A]
services [A] [C]
controllers
PersonController [A] [C]
I hope this helps to illustrate my true question. The footprint of annotation-based DI extends into the far reaches of the stack, whereas configuration-based DI is only used in the outermost (entry) application, where the composition root lives.

struts2 conversation and validation

I am working on a struts2 project that has interdependent forms.
I found struts2-conversation, stepped through their simple-example
and understood the conversation mechanism this far (please correct me if I got something wrong):
The Controller is mapped in the struts.xml
It holds the serializable ConversationContext and the Storing-Service
The ConversationContext holds POJOs mapped on forms by naming convention
Now my question is where to put the validation?
In this structure the controller is only one extending ConversationSupport and thereby ActionSupport supplying the validate, prepare and addField- & ActionError methods.
But validating within the controller would mean to validate the whole context, which does not really serve the issue.
I tried validation through annotation within the POJOs, within the context as described above which gives me some NullPointerException as if the context wasn't flushed and I think the xml-validation approach of struts2 is just too stiff. (btw how to let the generated javascripts be minified before being served? And why is there so many options?)
Mark's conversation-interceptor approach had similar problems coming up which's workarounds I didn't really get. Maybe you can help me there.
If you would like to use annotations on your model classes, it works fine with the plugin (as do the other validation approaches).
To validate your model, add #VisitorFieldValidator to the getModel() method in your controller. In the example app, you would then also add #VisitorFieldValidator to the getContact() and getPreferences() methods. Then you can use the validation annotations on the fields you wish to validate.
The service in the example is just there as a simple example of using an injected service in a Struts2 controller and how that can integrate easily with the conversation framework, but it is not directly related or needed (and I would recommend using either Spring, Guice, or CDI for dependency injection in the real world).
The ConversationContext class is intended mostly for internal use by the framework. You should be able to avoid interacting with it by using the annotations and conventions. Unless you simply wish to be adventurous.
To use XML validation in the example app, you would have to change the package name to remove the "struts2" word in order for the Struts2 resource loading tool to load the XML.

Get application components without #Autowired

How would you extract something prior 2.5 version from .xml config? It bothers me because if #Autowired is removed from my arsenal I would not really know what to do.
Say I want to use some DAO implementation.
In service class I usually write:
#Autowired
someDaoInterface generalDao;
Then I typically call
generalDao.someInterfaceMethod(someParam param);
How would I extract implementation from config in Spring 2.0 to use this method?
Is it as dumb as just: new ApplicationContext(pathToXml) and then use .getBean or there is other way?
Why do I ask for taking bean out from configuration file?
Because in Spring MVC how can you perform your logic without getting beans out from the application context.
If you have #Controller handler then you need to make calls to the service classes' methods? So they should be somehow retrieved from the context and the only way so far is using #Autowired? Then I would also want to populate Service classes as I stated in previous example with DAO classes and they also need to be retrieved from the application context, so I would be able to write logic for service classes themself. How would people do it in the past?
I see the #Autowired as the only mean of taking something out, not because it is convenient to wire automatically - I am perfectly ok with XML.
You still have option to wire it explicitely via property or constructor parameter. (Anyway, autowired is not going to work if there is ambiguity in your container )
Of course, you can use application context and getBean() in your java code, but it violates DI pattern and makes all the spring stuff useless. Purpose of DI is to decouple your business loginc from implementation details - it's not business logic it's how and where it dependencies come from. Dependencies are just there.
By using ApplicationContext.getBean() you are breaking this pattern, and introduce dependency to:
spring itself
your configuration names
After you done this, you can as well drop use of DI and spring because you just voided all the advandages DI is providing to you. (BTW, #Autowired also introduces dependency to spring, and violates DI pattern, it also implies that there is only one instance available)
Also, answer is: in ideal case there shall be no reference to spring in your code at all.
No imports, no annotations - just interfaces of collaborating entities.

Factory class vs Spring DI

As per my understanding both Factory class and Spring DI follows the Dependency injection. I mean in both the cases external entity is used to push the dependency. Right?
My question is which one i should go for between factory classes and Spring DI when my intention is just to get the objects . Assume i don't want any other features like aop, dao support etc. Only purpose is to get the objects either from Factory class or Spring DI. Which one is preferable.
on some site read this statement
DI loosely coupled and less intrusive in comparison to Factory classes
But could not get how spring DI loosely coupled and less intrusive than factory classes?
in both the cases we have to insert some kind of get object code in our core program .
Spring DI promotes loosely coupled code because the Spring container injects your dependencies based on configuration. If you are injecting interface implementations, you don't have to change code to change which specific implementation gets injected, unless you consider your configuration code, which many do.
If you use a Factory to create configured objects that are used by the rest of your code, you are writing code to create the objects, configure them, etc. If you want to change what the factory returns, you have to change actual code, which some would argue is a more intrusive change.
Typically Spring is used to configure how the various layers of your application are wired together. X service takes such and such DAO implementations, for example. That's application level organization. Lets say you have a scenario where want to create a button for every row in a list -- in that case you could use a factory to create the buttons. This scenario is based on a runtime situation where the GUI has different elements that you couldn't configure up front (because its based on the data), so DI makes less sense here.
EDIT - based on your comment questions, I think the primary point here is that you have to consider is that Spring is also an Inversion of Control container. That means you don't program in which components in your application go where. Without IoC, you might do something like
MyServiceImpl extends MyService {
Dao1 = new Dao1Impl(); // you programmatically configure which components go in here
Dao2 = new Dao2Impl();
....
}
instead you do something like
MyServiceImpl extends MyService {
public Dao1; // you haven't specified which components, only interfaces
public Dao2;
....
}
In the second code sample, Spring (or whatever you use) will inject the appropriate DAO instances for you. You have moved control of which components to use to a higher level. So IoC and DI go hand and hand, IoC promotes loose coupling because in your component definitions (i.e. interfaces) you only specify behavior.
In other words, IoC and DI are not necessary for loose coupling; you can have loose coupling with a Factory too
MyServiceImpl extends MyService {
public dao1
public dao2;
MyServiceImpl(){
dao1 = DaoFactory.getDao1();
...
}
....
}
here your service still only depends on DAO definitions and you use the factory to get implementations. The caveat is that your service is now coupled to the factory. You can make it more loose by passing a Factory into your constructor if you want....
Also, dont forget that Spring provides other useful functionalities, like its transaction management. That's incredibly helpful, even though you said for your app you don't need it.
But could not get how spring DI loosely coupled and less intrusive
than factory classes? in both the cases we have to insert some kind of
get object code in our core program .
Spring makes it less intrusive because it uses reflection to automatically "inject/create" the dependencies. Thus your code does not need a reference to a the factory.
Spring is generally used for "Singleton-like" object creation. People generally use custom factories for transient throw away object creation (like request objects).
In fact often times you will make Spring create and inject your custom factories (ie factory of a factory).

Spring - how to avoid implementation lock in between collaborating services

I am writing a small framework which uses spring for DI. I have a number of services which collaborate with each other.
ServiceA has reference to ServiceB - has reference to ServiceC etc. All these are prewired in spring configuration xml.
The issue occurs when the user tries to override one of these implementations, say ServiceB with his own, say ChildServiceB. Now, what I really want here is that the users ChildSerivceB should be wired into ServiceA. Can it be done in spring? If not, what is the best design pattern for this scenario?
Something like a late-binding for spring is what I am looking for.
I would like the user's spring configuration needs to be as minimal as possible in such scenarios.
Other Notes:
I use interfaces for all my services
To make it easy for people who use the default services, the spring congiuration framework-beans.xml is provided in the jar, they just need to instantiate it.
Users who want to override implementations can create their own beans.xml, but that is where I am stumped, how do they override the "wiring" of framework-beans.xml?
The issue occurs when the user tries to override one of these implementations, say ServiceB with his own, say ChildServiceB. Now, what I really want here is that the users ChildSerivceB should be wired into ServiceA. Can it be done in spring? If not, what is the best design pattern for this scenario?
1 Use Interface programming
2 Let user implement its own Service for ServiceB
3 Configure Bean in Spring xml
<bean name="serviceB" class="com.something.DefaultServiceBImpl"/>
now if you want user to have its own implementation just change it to
<bean name="serviceB" class="com.something.CustomServiceBImpl"/>
and in Class use interface

Categories

Resources