Objects initialization in spring framework - spring

i am studying spring framework i have some doubts to confirm:
I see that class objects are created as beans in xml file ... but my doubt is ... only pojo class beans need to be defined in xml for instatiation or all classes
eg: my custom code class EncryptionUtil class that helps in encrypting data and so on custom logic classes also need to be instantiated using beans?This is my primary concern
what about cases like i use
JSONObject j = new JSONOBJect() (External libs);
ArrayList<String> a = new ArrayList<String>();
( java default object and collections)
do these classes also need to have bean in xml?
i exactly dont know if spring ioc will instantiate each and every object or we need to instantiate only some objects
also, in spring app does "new " keyword work for creating objects
What should we use to instantiate bean in spring mvc ?
ie : like i used ApplicationContext in my spring app , should i get bean everywhere i need
will there be any problem if i use multiple annotations ie : of spring as well as hibernate on same class at same time?
eg: something like this
#Id #GeneratedValue
#Column(name = "id")
private int id;
but if i want id to be autowired too ...
#Autowired
#Id #GeneratedValue
#Column(name = "id")
private int id;
will this work?

Declare only classes as Spring Beans which you don't want to create with new. Further Spring Beans are normally singletons. This means there is only one instance of this class. In most cases Spring Beans are not POJOs. E.g mostly i declare DAOs, Service, Controller classes as Spring Beans.
No there is no need to declare these as Spring Beans.
Yes, new works. But these instances are not managed by the spring container. And you should only instantiate non spring beans with new. Spring Beans itself are instantiated by the Spring IOC container.
Inject beans to other beans with xml config or by annotation config (#Autowired).
You can mix spring annotations with annotations of other frameworks. But your example with the id doesn't work and makes no sense, since entity id's wont' be injected. Also your Hibernate entity must be also a spring bean (in this case declared as prototype). You can inject values and beans only to spring beans.

Related

IS Spring Context and Spring IOC container both are same and ApplicationContext is part of it?

I know what is application Context. It is an interface which provides spring beans.
All beans get initialized in Spring IOC containers.
But How all three are connected. Could you please explain.
Spring beans are the instances of classes that spring manages. You create classes and "mark" them to be spring managed (putting #Component, using #Bean in java configuration and so forth - there are many ways to tell spring that the instance of some particular class should be managed by spring)
When spring starts it creates an application context with is a registry of all beans it resolves.
Spring can inject one bean into another and its the way of spring to instantiate beans.
The principle of "providing dependencies by external container" as opposed to maintaining dependencies by class itself called Inversion of control, and spring implements this concept.
Update 1
There is no such a thing as "spring context" technically speaking
Spring IOC container is a framework that manages the beans (your classes) by means of providing a technical abstraction called application context (its a real interface in java with implementation inside the spring code).
In order to benefit from spring your Beans should have dependencies between them. In this case spring framework that implements IOC principle can "inject" (provide, resolve) dependencies between beans.
Here is an example:
#Component
class A {
}
#Component
class B {
#Autowired
private A a;
}
When spring container instantiates class B (creates the object : new B()) it "understands" that this instance (we call it bean because it's managed by spring) has a "dependency" on class A and since A is also managed by spring, it can "inject" (read put a value) into the property a of class B.
This is called an Inversion of Control. You, as a programmer do not have to instantiate property b by yourself, spring does it for you.

Spring Boot Scanning Classes from jars issue

In my sample spring boot application, i have added a dependency of a custom jar. My sample application has a support for web and jpa.
The jar which i've created contains a Spring MVC controller. Below is the sample code
#Controller
public class StartStopDefaultMessageListenerContainerController {
#Autowired(required=false)
private Map<String, DefaultMessageListenerContainer> messageListeners;
I haven't manually created a bean instance of this controller anywhere in my code.
Problem - When i start my spring boot application by running the main class, i get an error in console that prob while autowiring DefaultMessageListenerContainer.
My question here is, even though this class StartStopDefaultMessageListenerContainerController is just present in the classpath, it's bean shouldn't be created and autowiring should not happen. But spring boot is scanning the class automatically and then it tries to autowire the fields.
Is this the normal behavior of spring and is there anyway i can avoid this?
If the StartStopDefaultMessageListenerContainerController class is part of component scanning by spring container, Yes spring tries to instantiate and resolve all dependencies.
Here your problem is #Autowired on collection. Spring docs says,
Beans that are themselves defined as a collection or map type cannot be injected through #Autowired, because type matching is not properly applicable to them. Use #Resource for such beans, referring to the specific collection or map bean by unique name.
And also Refer inject-empty-map-via-spring

When to use Spring #Autowire annotation

Recently I had discussion with my friend regarding usage of Spring #Autowire annotation on entity(JPA) classes.
In our project we are using #Autowire annotaion to inject Entity but my friend suggesting not to use #Autowire annotaions on entity classes. When I asked why? He dont have the proper answer for that. So i just wanted to know are there any disadvantages using #Autowire annotaion on entity classes.
Also please explain when to go for #Autowire annotaion or not with example.
Thank in advance.
#Entity and #Autowire are not interchangeable.
#Entity annotation indicates that the JavaBean is a persistent entity.This is actually a JPA annotation and not a Spring Annotation.
#Entity will be used in the sessionFactory by the packagesToScan poroerty.
#Autowired: inject a resource by-type, i.e. by the class or by the interface of the annotated field or contractor. See my answer Inject and Resource and Autowired annotations
#Autowired is used to inject dependencies as an alternative to setting it via xml configurations
Maybe this answer will help you understand
Hibernate - spring annotated entities not scanned from within jar
UPDATE:
Following the comment bellow:
Company is your domain object, so you don't need to use spring in this case.
<bean id="company" class="xxx.Company"/>
The above will return the same instance with #autowire.
Even if you switch to scope="prototype" I don't see any reason to use spring for that.
You should have a service that will be used to CRUD company e.g.
CompanyService, this service will be a single tone so you will use #Autowire to inject it to the controller and it will use your JPA framework to implement CRUD's
To create a new company you will use:
Company c = new Company //this probably will be binded from your ui form
companyServic.saveOrUpdate(c);
See the following answer spring rest service - hibernate dao - annotations - pojo - namedqueries.
For common practice of DAO and services.
#Autowire is an annotation used to perform a dependency injection, its almost similar to the standard #Inject you can take a look at the spring reference manual to see the difference between those two annotations.
#Entity is a part of the jpa framework its used to mark a class as persistent, spring does not implement an equivalent annotation.

Clean way to inject a Spring 3 bean into a JSF 2 managed bean?

I'm migrating our current solution from JSF 1.2 to JSF 2. As I need to use the new View scope I'm using JSF 2 annotations. That forced me to inject the Spring beans using the JSF #ManagedProperty annotation instead of Spring's #Autowired
Before it was something like this:
#Autowired private OneService oneService
And now it's like:
#ManagedProperty(value="#{oneServiceImpl}")
private OneService oneService
Do you know if is there a way to annotate the managed properties without needing to state their bean name?
Thanks!
No, there isn't. JSF makes use of Expression Language (EL) to determine which class you refer by name. Using a class called ELResolver he takes the String passed, interprets and makes the appropriate reference. The class SpringBeanFacesELResolver provides integration between the two frameworks intercepts the request and passing it to the context of Spring, which handles the dependencies required to provide the ManagedBeans, who then passes it to the JSF's own ELResolver. So JSF needs the name of the bean to know what to inject.
You can still use Spring with JSF 2. Just create a custom Spring scope which can then be used as the view scope for your beans.
#Named #Scope("view")
public class MyBean {
#Inject
private MyManagedProperty oneService;
//...
}
Steal the implementation of the View scope here: http://cagataycivici.wordpress.com/2010/02/17/port-jsf-2-0s-viewscope-to-spring-3-0/

How does Spring annotation #Autowired work?

I came across an example of #Autowired:
public class EmpManager {
#Autowired
private EmpDao empDao;
}
I was curious about how the empDao get sets since there are no setter methods and it is private.
Java allows access controls on a field or method to be turned off (yes, there's a security check to pass first) via the AccessibleObject.setAccessible() method which is part of the reflection framework (both Field and Method inherit from AccessibleObject). Once the field can be discovered and written to, it's pretty trivial to do the rest of it; merely a Simple Matter Of Programming.
Java allows you to interact with private members of a class via reflection.
Check out ReflectionTestUtils, which is very handy for writing unit tests.
No need for any setter, you just have to declare the EmpDao class with the annotation #component in order that Spring identifies it as part of the components which are contained in the ApplicationContext ...
You have 2 solutions:
To manually declare your beans in the XML file applicationContext :
<bean class="package.EmpDao" />
To use automatic detection by seeting these lines in your context file:
<context:component-scan base-package="package" />
<context:annotation-config />
AND to use the spring annotation to declare the classes that your spring container will manage as components:
#Component
class EmpDao {...}
AND to annotate its reference by #Autowired:
#Component (or #Controller, or #Service...)
class myClass {
// tells the application context to inject an instance of EmpDao here
#Autowired
EmpDao empDao;
public void useMyDao()
{
empDao.method();
}
...
}
Autowiring happens by placing an instance of one bean into the desired field in an instance of another bean. Both classes should be beans, i.e. they should be defined to live in the application context.
Spring knows the existence of the beans EmpDao and MyClass and will instantiate automatically an instance of EmpDao in MyClass.
Spring uses the CGLib API to provide autowired dependency injection.
References
Usage of CGLib forum comment by Rod Johnson
3.3.1. Injecting dependencies
Pro Spring - Analyzing Spring Dependencies
Further Reading
Introduction to the Spring Framework by Rod Johnson

Resources