Spring IOC & Configuration
Working Example: https://github.com/teachkoka/spring-ioc-xml-b8
Spring IOC Container:
It is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes, or a mechanism such as the Service Locator pattern.
A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.
**In simple terms, passing required parameters to classes through xml configuration.
Dependency Injection nothing but Inversion of Control (IoC) because the normal control sequence would be the object finds the objects it depends on by itself and then calls them. Here, this is reversed: The dependencies are handed to the object when it's created
The interface org.springframework.context.ApplicationContext
represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the aforementioned beans. The container gets its instructions on what objects to instantiate, configure, and assemble by reading configuration metadata.
org.springframework.beans
org.springframework.context
2 Types of IOC Containers:
.Core Container: Bean Factory
.J2EE Container: Application Context
Container responsibilities:
1)Create instances
2)Dependency Injection
3)LifeCycle Management
Bean Factory(Core) container :
.At the time of container startup – Loads the spring xml file and parse the xml file wellformed or not and validates the tags using sax parser .
.Creates the instance of the bean when the user request for the bean.
By default all the beans configured in are singleton.
Resource resource = new ClassPathResource("beans.xml"); BeanFactory factory = new XmlBeanFactory(resource);
Application context(J2EE) container :
.At the time of container startup – Loads the spring xml file and parse the xml file well-formed or not and validates the tags using sax parser.
.Creates the instance of all the beans, with singleton scopes, at the time of application start-up. If bean scope is prototype, at the time of each request bean insatnce will be created.
.By default all the beans configured are singleton.
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
Dependency Injection can be achieved either through setter method or construtors.
Using dependency injection we can inject any datatype
1. primitive injection
2. reference injection
Points to remember :
.IOC container designed to load in such a way that it will load private construtor classes as well.
.One setter method will take only one input parameter.
–primitive
<bean id="" class="" scope=""> <property name="" value=""/> </bean>
–List (Arraylist)
<bean id="" class="" scope=""> <property name=""> <set> <value> </value> <value> </value> </set> </property> </bean>
–Map (LinkedHashMap)
<bean id="" class="" scope=""> <property name=""> <map> <entry key="" value=""/> <entry key="" value=""/> </map> </property> </bean>
–property
xmlns:util xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<bean id="t" class="com.bellinfo.corejava.Test">
<property name="driver">
<util:properties location="classpath:drivers.properties"/>
</property>
</bean>
.Constructor :
<bean id="" class=""> <constructor-arg name ="" value="" /> <constructor-arg name ="" value=""/> </bean> <bean id="" class=""> <constructor-arg value="" index=""/> <constructor-arg value="" index=""/> </bean> <bean id="" class=""> <constructor-arg value="" index="0" type="java.lang.String"/> <constructor-arg value="" index="1" type="int"/> </bean>
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies.
To make setter dependency injection mandatory, using dependency-check. By default, its 'none' (simple – for primitive, objects – for objects, all- for all kind)
@Required –> RequiredAnnotationBeanPostProcessor
depends-on – If class A is depending on class B then
<bean id="a" class="A" depends-on="b"> <bean id="b" class="B">
p-namespace – property
c-namespace – constructor
—————
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/p"
By default, ApplicationContext implementations eagerly create and configure all singleton beans as part of the initialization process. Generally, this pre-instantiation is desirable, because errors in the configuration or surrounding environment are discovered immediately, as opposed to hours or even days later. When this behavior is not desirable, you can prevent pre-instantiation of a singleton bean by marking the bean definition as lazy-initialized. A lazy-initialized bean tells the IoC container to create a bean instance when it is first requested, rather than at startup.
In XML, this behavior is controlled by the lazy-init attribute on the <bean/> element; for example:
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>
<bean name="not.lazy" class="com.foo.AnotherBean"/>
When the preceding configuration is consumed by an ApplicationContext, the bean named lazy is not eagerly pre-instantiated when the ApplicationContext is starting up, whereas the not.lazy bean is eagerly pre-instantiated.
However, when a lazy-initialized bean is a dependency of a singleton bean that is not lazy-initialized, the ApplicationContext creates the lazy-initialized bean at startup, because it must satisfy the singleton’s dependencies. The lazy-initialized bean is injected into a singleton bean elsewhere that is not lazy-initialized.
Autowiring :
.Injecting dependency automatically
.Can be applied only to secondary datatypes
It can be done through
.byType
.byName
.constructor
.autodetect
.no (default)
<bean id="t1" class="com.bellinfo.corejava.Test" autowire="byName"> <bean id="t1" class="com.bellinfo.corejava.Test" autowire="byType"> <bean id="t1" class="com.bellinfo.corejava.Test" autowire="constructor"> <bean id="t1" class="com.bellinfo.corejava.Test" autowire="default"> <bean id="t1" class="com.bellinfo.corejava.Test" autowire="no">
–byType, byName, autodectect – for settertype dependecy injection
–constructor, autodetect – for constructor dependency
–byType ambiguity can be resolved through autowire-candidate="false"
–If you want to apply for all the beans that are there in the xml file then use default-autowire="byType" at root-element
<beans default-autowire="byType"></beans>
–byName, you don't encounter any ambiguity
–constructor, internally it use byType mechanism
–autoDetect
.if default constructor, parameter constructors and setter Injection then it will choose default constructor for instance creation and setter Injection for dependency Injection.
.if parameter constructors and setter Injection then it will choose default constructor for both instance creation and injection.
@Autowired( uses byType), to resolve ambiguity use @Qualifier(value="id");
In order to activate autowired annotation,
<context:annotation-config/>
Spring reduces the configuration of creating the objects of classes by auto-scanning & stereotype annotations
1 Singleton -(Default) Scopes a single bean definition to a single object instance per Spring IoC container.
prototype – Scopes a single bean definition to any number of object instances.
2.Request Scopes – A single bean definition to the lifecycle of a single HTTP request; that is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
3.Session Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
4.GlobalSession Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a Portlet context. Only valid in the context of a web-aware Spring ApplicationContext.
5.Application Scopes – a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
Is Java Singleton different from Spring Singleton?
YES, YES, YES
Java considers something a singleton if it cannot create more than one instance of that class within a given class loader, whereas Spring would consider something a singleton if it cannot create more than one instance of a class within a given container/context.
4 stereotype annotations
1)@Controller (on Spring MVC for Controller)
2)@Repository (on DAO classes)
3)@Service (on business logic classes)
4)@Component (non MVC classes, for any utility class)
in order to auto-scan all the classes, you can use
<context:component-scan base-package="com.bellinfo"/>
– static dependency injection can achieved through MethodInvokingFactoryBean
for Sun created singleton classes or others – we need to use factory methods like getInstance() to create an objects
factory-method ="getInsatnce()"
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="com.bellinfo.corejava.Netflix.setFruits"/> <property name="arguments"> <list> <value>apple</value> </list> </property> </bean>
Examples of singleton classess,
SessionFactory
ResourceBundle
If you want to create an instance from Factory bean instance, then
<bean id="sf" class="SessionFactory"/> <bean id="s" factory-bean="sf" class="Session" factory-method="openSession"/>
Lifecycle methods: By IOC container we can maintain simple pojo classes life cycle.
-In order to achieve this, we need to use ConfigurableApplicationContext(also J2EE) Container.
-Bean life cycle can be achieved in 3 ways
Programatic approach
-implement InitializingBean, DisposableBean
Declarative/xml configuration approach
-init-method=""
-destroy-method=""
Annotation approach: to activate inject DI -CommonAnnotationBeanPostProcessor
@PostConstruct
@PreDestroy
–Default life cycle for entire configuration then at root element configure
default-destroy-method="" default-init-method=""
LookUp methods: A method which required an implementation is called lookup method.
Spring internally generates proxyclass and return that object.
method replacer :
-by implements MethodReplacer
– <bean> <replaced-method name="{methodName}" replacer="new implemented class ref"/> </bean>
JDK also provides support for annotations,
@Resource(byName) -(same as @Autowired)
@Inject(first byName – if not matches byType) – (same as @Autowired)
J2EE also support stereotype annotations
@Named
Properties files data in to classes:
Properties dependencies injection using expression
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="Location" value="resources/drivers.properties"></property> </bean> <bean id="c" class="beans.DB"> <property name="driver" value=${driver}> </property> </bean>
I18N
-provides language support
– All property file should end with corresponding language (like _en, _te)
– Support 200+ languages
Implementation Steps:
1)
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource;">
<property name="basename" value="resources/filename"/>
</bean>
2)
<%@page import ="java.util.Locale"%>
<%
String lang = request.getHeader("accept-language");
Locale locale= new Locale(lang);
ApplicationContext ap = new ClassPathXmlApplicationContext("spring-config.xml");
String value = ap.getMessage("label", null, locale);
%>
<form action="/hello">
<%=value%>: <input type="text" name="name"/>
<input type="submit" value="submit"/>
</form>
http://vikku.info/indian-language-unicode-converter/telugu-unicode-converter.html
L10N – validation support and business project
Listeners :
1) Implement ApplicationListners<>
These are the four different events avaliable at Spring
ContextStartedEvent
ContextStoppedEvent
ContextRefreshEvent
ContextCloseEvent
2)Configure your classes in spring config file
3)Use Configurable application Context