Q: What is IOC (or Dependency Injection)?
A: The basic concept of the Inversion of Control pattern (also known as dependency injection) is that you do not create your objects but describe how they should be created. You don't directly connect your components and services together in code but describe which services are needed by which components in a configuration file. A container (in the case of the Spring framework, the IOC container) is then responsible for hooking it all up.
Q: What are the different types of IOC (dependency injection) ?
A: Constructor Injection (e.g. Pico container, Spring etc): Dependencies are provided as constructor parameters.
Setter Injection (e.g. Spring): Dependencies are assigned through JavaBeans properties (ex: setter methods).
Interface Injection (e.g. Avalon): Injection is done through an interface.
Spring supports only Constructor and Setter Injection
<bean id="Spring3HelloWorldBean"
class="com.test.main.Spring3HelloWorld" >
<!-- Constructor Injection
<constructor-arg type="java.lang.String" value="Ganesh" />
<constructor-arg type="int" value="20" />
-->
<!-- Setter Injection -->
<property name="name" value="Eswar" />
<property name="age" value="24"/>
</bean>
Q: What are the advantages of Spring framework?
A:
Q:What is the difference between Bean Factory and Application Context ?
A: Main difference is "Lazy loading vs. pre-loading beans with Spring Framework"
Spring framework can instantiate and bind (called loading) related Java objects (called beans) according to a given configuration. An XML file can easily be used to define these bindings. Spring framework supports two different types of loading methods; lazy loading and pre-loading respectively managed by BeanFactory and ApplicationContext containers.
Lazy Loading
A bean is loaded only when an instance of that Java class is requested by any other method or a class. org.springframework.beans.factory.BeanFactory (and subclasses) container loads beans lazily. Following code snippet demonstrate lazy loading, concentrate on how "beans.xml" spring configuration file is loaded by BeanFactory container class.
BeanFactory factory = new XmlBeanFactory(
new InputStreamResource(
new FileInputStream("beans.xml"))); // 1
Employee emp = (Employee) factory.getBean("employeeBean"); // 2
Even though "beans.xml" configuration file is loaded with BeanFactory container in line number 1, none of the beans will be instantiated. Instantiation takes place only at line number 2, where bean called "employeeBean" is requested from container. Since the class is instantiated at getBean() method call, time spend to return this method will vary depending on the instantiated object.
Pre-loading
All beans are instantiated as soon as the spring configuration is loaded by a container. org.springframework.context.ApplicationContext container follows pre-loading methodology.
ApplicationContext context =
new ClassPathXmlApplicationContext("beans.xml"); // 1
Employee emp = (Employee) context.getBean("employeeBean"); // 2
As all singleton beans are instantiated by container at line number 1, this line will take some considerable time to complete. However line number 2 will return the bean instance immediately since instances are already available inside the container.
Decision should be taken based on the requirement of when the instance should be created also think about the memory as ApplicationContext loads all the instances specified in the config file all together.
Q:Autowiring collaborators
Constructor Injection vs. Setter Injection
If the question is which one is better, go with constructor injection
Setter-Injection
The basic-ideas is that you have a no argument-constructor which creates the object with “reasonable-defaults” .
Constructor-Injection
The basic idea with constructor-injection is that the object has no defaults and instead you have a single constructor where all of the collaborators and values need to be supplied before you can instantiate the object. At first it may seem that setter injection is preferred since you have no argument constructors which will make it easy for you to create the object in production and test. However, there is one non-obvious benefit with constructor injection, which in my opinion makes it a winner. Constructor-injection enforces the order of initialization and prevents circular dependencies. With setter-injection it is not clear in which order things need to be instantiated and when the wiring is done. In a typical application there may be hundreds of collaborators with at least as many setter calls to wire them together. It is easy to miss a few setter calls when wiring the application together. On the other hand constructor-injection automatically enforces the order and completeness of the instantiated.
For example lets say we are making DB connection, so the order of flow will be some what like this
ServiceClass->Create DataSource->Init DAOImpl->DAOImpl.getInfoFromDB
In constructor injection we can insure this order by creating a DAOImpl constructor like DAOImpl(ds)
Circular Dependency
If you have a UserService that needs to get information about an employer from CompanyService and the CompanyService needs information about employees from UserService, right there you have a circular dependency.
Spring Bean Scopes Example
OutPut
Without scope="prototype"
Message : Message by custA
Message : Message by custA
With scope="prototype"
Message : Message by custA
Message : null
Bean life cycle
When a bean is instantiated, it may be required to perform some initialization to get it into a usable state. Similarly, when the bean is no longer required and is removed from the container, some cleanup may be required. Though, there is lists of the activities that take place behind the scenes between the time of bean Instantiation and its destruction lets discuss only two important bean lifecycle callback methods which are required at the time of bean initialization and its destruction.
Initialization callbacks:
To define setup and teardown for a bean, we simply declare the <bean> with init-method and/or destroy-method parameters. The init-method attribute specifies a method that is to be called on the bean immediately upon instantiation. Similarly, destroy-method specifies a method that is called just before a bean is removed from the container.
Example
package com.test.lifecycle;
import org.springframework.beans.factory.InitializingBean;
public class ExampleBean implements InitializingBean {
public void afterPropertiesSet() {
System.out.println("Inside Init");
}
}
XML based config
Destruction callbacks
public class ExampleBean implements DisposableBean {
public void destroy() {
System.out.println("Inside Destroy");
}
}
XML config
<bean id="exampleBean"
class="examples.ExampleBean" destroy-method="destroy"/>
A: The basic concept of the Inversion of Control pattern (also known as dependency injection) is that you do not create your objects but describe how they should be created. You don't directly connect your components and services together in code but describe which services are needed by which components in a configuration file. A container (in the case of the Spring framework, the IOC container) is then responsible for hooking it all up.
Q: What are the different types of IOC (dependency injection) ?
Setter Injection (e.g. Spring): Dependencies are assigned through JavaBeans properties (ex: setter methods).
Interface Injection (e.g. Avalon): Injection is done through an interface.
Spring supports only Constructor and Setter Injection
<bean id="Spring3HelloWorldBean"
class="com.test.main.Spring3HelloWorld" >
<!-- Constructor Injection
<constructor-arg type="java.lang.String" value="Ganesh" />
<constructor-arg type="int" value="20" />
-->
<!-- Setter Injection -->
<property name="name" value="Eswar" />
<property name="age" value="24"/>
</bean>
Q: What are the advantages of Spring framework?
A:
- Spring has layered architecture. Use what you need and leave you don't need now.
- Spring Enables POJO Programming. There is no behind the scene magic here. POJO programming enables continuous integration and testability.
- Dependency Injection and Inversion of Control Simplifies JDBC
- Open source and no vendor lock-in.
Q:What is the difference between Bean Factory and Application Context ?
A: Main difference is "Lazy loading vs. pre-loading beans with Spring Framework"
Spring framework can instantiate and bind (called loading) related Java objects (called beans) according to a given configuration. An XML file can easily be used to define these bindings. Spring framework supports two different types of loading methods; lazy loading and pre-loading respectively managed by BeanFactory and ApplicationContext containers.
Lazy Loading
A bean is loaded only when an instance of that Java class is requested by any other method or a class. org.springframework.beans.factory.BeanFactory (and subclasses) container loads beans lazily. Following code snippet demonstrate lazy loading, concentrate on how "beans.xml" spring configuration file is loaded by BeanFactory container class.
BeanFactory factory = new XmlBeanFactory(
new InputStreamResource(
new FileInputStream("beans.xml"))); // 1
Employee emp = (Employee) factory.getBean("employeeBean"); // 2
Even though "beans.xml" configuration file is loaded with BeanFactory container in line number 1, none of the beans will be instantiated. Instantiation takes place only at line number 2, where bean called "employeeBean" is requested from container. Since the class is instantiated at getBean() method call, time spend to return this method will vary depending on the instantiated object.
Pre-loading
All beans are instantiated as soon as the spring configuration is loaded by a container. org.springframework.context.ApplicationContext container follows pre-loading methodology.
ApplicationContext context =
new ClassPathXmlApplicationContext("beans.xml"); // 1
Employee emp = (Employee) context.getBean("employeeBean"); // 2
As all singleton beans are instantiated by container at line number 1, this line will take some considerable time to complete. However line number 2 will return the bean instance immediately since instances are already available inside the container.
Decision should be taken based on the requirement of when the instance should be created also think about the memory as ApplicationContext loads all the instances specified in the config file all together.
Q:Autowiring collaborators
A: The Spring container is able to autowire relationships between collaborating beans. This means that it is possible to automatically let Spring resolve collaborators (other beans) for your bean by inspecting the
contents of the BeanFactory. The autowiring functionality has five modes. Autowiring is specified per bean and can thus be enabled for some beans, while other beans will not be autowired. Using autowiring, it is possible to reduce or eliminate the need to specify properties or constructor arguments, thus saving a significant amount of typing. [2] When using XML-based configuration metadata, the autowire mode for a bean definition is specified by using the autowire attribute of the <bean/> element. The following values are allowed:
- no :No autowiring at all
- byName :Autowiring by property name
- byType :Allows a property to be autowired if there is exactly one bean of the property type in the container. If there is more than one, a fatal exception is thrown, and this indicates that you may not use byType autowiring for that bean. If there are no matching beans, nothing happens; the property is not set
- constructor :This is analogous to byType, but applies to constructor arguments
- autodetect :Chooses constructor or byType through introspection of the bean class
Q: Given the following class called Car:
public class Cat { public void eat() { System.out.println("Eating"); } }
And given the following Spring config file carconfig.xml:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation=
5 "http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
7
8 <bean id="smallCat" class="Cat" />
Which of the below actions would cause the String "Eating" to be printed out to the console
directly after Spring had initialized the bean called goodCar?
A: Modify line 8 in carconfig.xml to:
<bean id="goodCar" class="Car" init-method="tune" />
Spring AOP
- Aspect - Think of this as the general feature you want to apply globally to your application (logging, performance monitoring, exception handling, transaction management, etc).
- Advice - A chunk of code that is invoked during program execution, and is a piece of the logic for implementing your aspect. This is the first important piece of a Spring AOP aspect implementation! I like to compare advice implementations to the decorator pattern. While an advice doesn't necessarily wrap an entire object in concept, it has the same general effect. We'll learn in a bit that how that advice is applied is more granular/formal than typically defined in the decorator pattern however.
- Joinpoint - A *single* location in the code where an advice should be executed (such as field access, method invocation , constructor invocation, etc.). Spring's built-in AOP only supports method invocation currently, so joinpoints aren't particularly important to focus on at this point.
- Pointcut - A pointcut is a set of many joinpoints where an advice should be executed. So if, in Spring, a joinpoint is always a method invocation, then a pointcut is just a set of methods that, when called, should have advices invoked around them. This is the second important pieces of a Spring AOP aspect implementation!
- Targets/Target Objects - The objects you want to apply an aspect or set of aspects to!
- Introduction - This is the ability to add methods to an object. This is closely tied to, and is almost analogous to the term 'mixins'. It's really just a way to make an object of type A also an object of type B. Introduction in Spring is limited to interfaces.
Constructor Injection vs. Setter Injection
If the question is which one is better, go with constructor injection
Setter-Injection
The basic-ideas is that you have a no argument-constructor which creates the object with “reasonable-defaults” .
Constructor-Injection
The basic idea with constructor-injection is that the object has no defaults and instead you have a single constructor where all of the collaborators and values need to be supplied before you can instantiate the object. At first it may seem that setter injection is preferred since you have no argument constructors which will make it easy for you to create the object in production and test. However, there is one non-obvious benefit with constructor injection, which in my opinion makes it a winner. Constructor-injection enforces the order of initialization and prevents circular dependencies. With setter-injection it is not clear in which order things need to be instantiated and when the wiring is done. In a typical application there may be hundreds of collaborators with at least as many setter calls to wire them together. It is easy to miss a few setter calls when wiring the application together. On the other hand constructor-injection automatically enforces the order and completeness of the instantiated.
For example lets say we are making DB connection, so the order of flow will be some what like this
ServiceClass->Create DataSource->Init DAOImpl->DAOImpl.getInfoFromDB
In constructor injection we can insure this order by creating a DAOImpl constructor like DAOImpl(ds)
Circular Dependency
If you have a UserService that needs to get information about an employer from CompanyService and the CompanyService needs information about employees from UserService, right there you have a circular dependency.
Spring Bean Scopes Example
5 types of bean scopes supported :
singleton – Return a single bean instance per Spring IoC container
prototype – Return a new bean instance each time when requested
request – Return a single bean instance per HTTP request.
session – Return a single bean instance per HTTP session.
globalSession – Return a single bean instance per global HTTP session.
If no bean scope is specified in bean configuration file, default to singleton.
package com.test.scopes;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest
{
public static void main( String[] args )
{
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"bean.xml"});
CustomerService custA = (CustomerService)context.getBean("customerService");
custA.setMessage("Message by custA");
System.out.println("Message : " + custA.getMessage());
//retrieve it again
CustomerService custB = (CustomerService)context.getBean("customerService");
System.out.println("Message : " + custB.getMessage());
}
}
package com.test.scopes;
public class CustomerService {
String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="customerService"
class="com.test.scopes.CustomerService" scope="prototype"/>
</beans>
Without scope="prototype"
Message : Message by custA
Message : Message by custA
With scope="prototype"
Message : Message by custA
Message : null
Bean life cycle
When a bean is instantiated, it may be required to perform some initialization to get it into a usable state. Similarly, when the bean is no longer required and is removed from the container, some cleanup may be required. Though, there is lists of the activities that take place behind the scenes between the time of bean Instantiation and its destruction lets discuss only two important bean lifecycle callback methods which are required at the time of bean initialization and its destruction.
Initialization callbacks:
To define setup and teardown for a bean, we simply declare the <bean> with init-method and/or destroy-method parameters. The init-method attribute specifies a method that is to be called on the bean immediately upon instantiation. Similarly, destroy-method specifies a method that is called just before a bean is removed from the container.
Example
package com.test.lifecycle;
import org.springframework.beans.factory.InitializingBean;
public class ExampleBean implements InitializingBean {
public void afterPropertiesSet() {
System.out.println("Inside Init");
}
}
XML based config
<bean id="exampleBean"
class="com.test.lifecycle.ExampleBean" init-method="init"/>
Destruction callbacks
public class ExampleBean implements DisposableBean {
public void destroy() {
System.out.println("Inside Destroy");
}
}
XML config
<bean id="exampleBean"
class="examples.ExampleBean" destroy-method="destroy"/>
No comments:
Post a Comment