1 © Luxoft Training 2012 Spring Framework Inversion of control Part 1
2 © Luxoft Training 2012 Spring Framework :: Introduction Spring is a lightweight, but at the same time flexible and universal framework used for creating Java SE and Java EE applications; Spring is a framework with an open source code; Spring is an application framework, not a layer framework; Spring includes several separate frameworks;
3 © Luxoft Training 2012 Spring Framework :: Introduction Rod Johnson created Spring in 2003; Spring took its rise from books Expert One-on-One Java J2EE Design and Development and J2EE Development Without EJB; The basic idea behind Spring is to simplify traditional approach to designing J2EE applications;
4 © Luxoft Training 2012
5 Spring Framework :: Framework Structure
6 © Luxoft Training 2012 Spring Framework :: Object dependencies Traditional approach PersonCompany class Person { public String name; public Company company; public Person() { String name = John Smith; Company company = new Company(); company.name = Luxoft; } class Company { public String name; }
7 © Luxoft Training 2012 Problems: o Class A directly depends on class B o Its impossible to test A separately from B o Lifetime of B object depends on A – its impossible to use B object in other places o Its not possible to replace B to another implementation AB Traditional approach Spring Framework :: Object dependencies
8 © Luxoft Training 2012 Approach with use of Singleton pattern SmithPersonLuxoftCompany class SmithPerson extends Person { public Person smithPerson = new Person(); public static Person create() { smithPerson.name = John Smith; smithPerson.company = LuxoftCompany.create(); return smithPerson; } class LuxoftCompany extends Company { public Company luxoftCompany = new Company(); public LuxoftCompany() { luxoftCompany = Luxoft; } public static Company create() { return luxoftCompany; } class Person { public String name; public Company company; } class Company { public String name; } Spring Framework :: Object dependencies
9 © Luxoft Training 2012 SmithPersonLuxoftCompany -Sepatate class specially for our task -Theres a direct link to LuxoftCompany in SmithPerson.create() -In case of transfer Smith to another company we have to change a code -Its impossible to temporally replace company for testing Approach with use of Singleton pattern Spring Framework :: Object dependencies
10 © Luxoft Training 2012 PersonCompany Inversion of Control Container approach <property name=companyReport" ref=companyReport"/> POJO – plain old Java Objectapplication-context.xml class Person { public String name; public Company company; } class Company { public String name; } class private CR companyReport; public void setCompanyReport() ; Spring Framework :: Object dependencies
11 © Luxoft Training 2012 PersonCompany Advantages: -Container creates necessary objects and manage its lifetime -Person and Company are not depended and not depend on any outer libraries -application-context documents the system and objects dependencies -Its very easy to make changes to object dependencies in the system Spring Framework :: Object dependencies Inversion of Control Container approach
12 © Luxoft Training 2012 AB AB JNDI repository Name B_NAME to look for B Register in JNDI under the B_NAME Traditional approach: dependencies inside the code Service Locator (JNDI в JEE) pattern: objects in the repository IoC: objects know nothing about each other AB Application context - Creates A object - Initialize - Creates A object -Initialize and inject B object dependency class A { private B b; } class B { } Spring Framework :: Object dependencies
13 © Luxoft Training 2012 Spring Framework :: IoC / DI Inversion of Control (IoC) pattern is the basis for Spring –Hollywood Principle – Don't call me, I'll call you (Could you recall any design pattern from GoF catalog to which this slogan can be applied? ); –Basic idea is to eliminate dependency of application components from certain implementation and to delegate IoC container rights to control classes instantiation; Martin Fowler suggested the name Dependency Injection (DI) because it better reflects the essence of the pattern (
14 © Luxoft Training 2012 Spring Framework :: IoC / DI Advantages of IoC containers: Dependency management and applying changes without recompiling; Facilitates reusing classes or components; Simplified unit testing; Cleaner code (classes dont initiate auxiliary objects); Its especially recommended to put those objects which implementation may change to the IoC container
15 © Luxoft Training 2012 Spring Framework :: IoC Containers BeanFactory is a central IoC container interface in Spring Framework (implementation used is XmlBeanFactory): –BeanFactory provides only basic low-level functionality; ApplicationContext is an interface enhancing BeanFactory and adding these features to the basic container features: –Simple integration with Spring AOP; –Work with resources and messages; –Event handling; –Support for internationalization; –Specific application contexts (for example, WebApplicationContext); It is Application Contexts that are used in a real life; BeanFactory could be used in exceptional cases, for example, if integrating Spring with a framework or when resources are critical and only IoC container is required.
16 © Luxoft Training 2012 Spring Framework :: IoC Containers There are several available implementations of ApplicationContext. Most widely used are: – GenericXmlApplicationContext (since v.3.0); – ClassPathXmlApplicationContext ; – FileSystemXmlApplicationContext ; – WebApplicationContext ; XML is a traditional way to configure container, though there are some other ways to configure metadata (annotations, Java code, etc.); In most cases it is easier and faster to use annotation-based configuration. However, you have to remember that annotation-based configuration has some restrictions and introduces additional code-level dependencies; Generally, user (developer) wont have to initiate Spring IoC container on his or her own;
17 © Luxoft Training 2012 Spring Framework :: Working with IoC Container In general, work of Spring IoC container can be represented as follows: When instantiating and initiating container, your application classes are combined with metadata (container configuration) and at the output you get fully configured and ready-to-work application.
18 © Luxoft Training 2012 Spring Framework :: Working with IoC Container Container creation: public void main(String args[]) { ApplicationContext context = new ClassPathXmlApplicationContext(application-context.xml"); BankApplication bankApplication = context.getBean(bankApplication); } ApplicationContext context = new ClassPathXmlApplicationContext( new String[] {"services.xml", "daos.xml"});
19 © Luxoft Training 2012 Spring Framework :: Working with IoC Container Configuration example: <beans xmlns=" xmlns:xsi=" xsi:schemaLocation="
20 © Luxoft Training 2012 Spring Framework :: Bean creation With the use of constructor: <bean id=clientService" class="ru.luxoft.training.samples.ClientService" /> With the use of a factory method: <bean id="clientService" class="ru.luxoft.training.samples.ClientService" factory-method="createInstance" /> class ClientService { public static ClientService createInstance() { ClientService cs = new ClientService(); // possibly perform some other operations // with cs instance return cs; }
21 © Luxoft Training 2012 With the use of not static factory method: <bean id="serviceFactory" class="examples.DefaultServiceFactory" /> <bean id="clientService" factory-bean="serviceFactory" factory-method="createClientServiceInstance" /> class DefaultServiceFactory { public ClientService createClientServiceInstance() { ClientService cs = new ClientService(); // possibly perform some other operations // with cs instance return cs; } Spring Framework :: Bean creation
22 © Luxoft Training 2012 Spring Framework :: Lazy initialization Lazy initialization is used to postpone bean creation to the time its first adressed. Lazy initialization of single bean: <bean id=lazy" class=ru.luxoft.training.ClientService" lazy-init=true" /> Lazy initialization of all beans in a container: … If singleton bean depends on lazy bean, lazy bean will be created in the moment of singleton bean creation.
23 © Luxoft Training 2012 Spring Framework :: Context import Its often convinient to break context to several files:
24 © Luxoft Training 2012 Spring Framework :: Use of property files with context <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> jdbc.driverClassName=org.hsqldb.jdbcDriver jdbc.url=jdbc:hsqldb:hsql://production:9002 jdbc.username=sa jdbc.password=root jdbc.properties:
25 © Luxoft Training 2012 Spring Framework :: Use of alias In this case bean named originalName may be referred to as aliasName; Used to provide future bean specialization. For example, we may refer beans as serviceCompany and itCompany, but for a while we have no special implementation for it, we use aliases:
26 © Luxoft Training 2012 Spring Framework :: Constructor DI Dependency injection with use of constructor public class ConstructorInjection { private Dependency dep; private String descr; public ConstructorInjection(Dependency dep, String descr) { this.dep = dep; this.descr = descr; }
27 © Luxoft Training 2012 Spring Framework :: Constructor DI Cyclic dependency: We will get BeanCurrentlyInCreationException duting DI Solution: to replace Constructor DI to Setter DI in one or both classes
28 © Luxoft Training 2012 Spring Framework :: Setter DI public class SetterInjection { private Dependency dep; private String descr; public void setDep(Dependency dep) { this.dep = dep; } public void setDescr(String descr) { this.descr = descr; }
29 © Luxoft Training 2012 Spring Framework :: Autowiring Example: service class to get user info UserDirectory LDAPUserDirectory DatabaseUserDirectory MockUserDirectory class LoginManager { UserDirectory userDirectory; } class UserDirectorySearch { UserDirectory userDirectory; } class UserInfo { UserDirectory userDirectory; } Let we have classes which need the information about the user <bean id=userDirectorySearch class=UserDirectorySearch>
30 © Luxoft Training 2012 Spring Framework :: Autowiring Now lets turn on the autowiring class LoginManager { UserDirectory userDirectory; } class UserDirectorySearch { UserDirectory userDirectory; } class UserInfo { LDAPUserDirectory ldapUserDirectory; } userDirectory property is initialized automatically:
31 © Luxoft Training 2012 Spring Framework :: Autowiring Spring is able to autowire (add dependencies) beans instead of ; In some cases it can significantly reduce the volume of configuration required; Can cause configuration to keep itself up to date as your object model evolve (for example, if you need to add an additional dependency, that dependency can be satisfied automatically); Autowiring by type can only work if there is exactly one bean of a property type; Harder for reading and checking dependencies than explicit wiring; Specified with autowire attribute in bean definition <bean id="..." class="..." autowire=no|byName|byType|constructor" />
32 © Luxoft Training 2012 Spring Framework :: Autowiring Autowiring modes: –no: no autowiring at all. This is the default; –byName: autowiring by property name. This option will inspect the container and look for a bean with ID exactly the same as the property which needs to be autowired. If such a bean cannot be found, the object is not autowired; –byType: autowiring by type. Works only if there is exactly one bean of property type in container. If there is more than one, then UnsatisfiedDependencyException is thrown; –constructor: container looks for a bean (or beans) of the constructor argument type. If there is more than one bean type or more than one, then UnsatisfiedDependencyException is thrown;
33 © Luxoft Training 2012 Spring Framework :: Collections initialization public class Customer { private List list; private Set set; private Map map; private Properties props; } 1
34 © Luxoft Training Spring Framework :: Collections initialization public class Customer { private List list; private Set set; private Map map; private Properties props; }
35 © Luxoft Training 2012 Spring Framework :: Collections initialization public class Customer { private List list; private Set set; private Map map; private Properties props; }
36 © Luxoft Training 2012 Spring Framework :: Collections initialization The same as: CustomerBean customerBean = context.getBean(customerBean); customerBean.getMap().put("Key 1", new Integer(1)); customerBean.getMap().put("Key 2", context.getBean("personBean)); Person p = new Person(); p.setName("Ivan"); p.setAddress("address"); p.setAge(28); customerBean.getMap().put("Key 3", p);
37 © Luxoft Training Spring Framework :: Collections initialization public class Customer { private List list; private Set set; private Map map; private Properties props; }
38 © Luxoft Training 2012 <bean id="inheritedTestBean" abstract="true" class="org.springframework.beans.TestBean"> <bean id="inheritsWithDifferentClass" class="org.springframework.beans.DerivedTestBean" parent="inheritedTestBean" init-method="initialize"> Spring Framework :: Properties inheritance
39 © Luxoft Training child.admin s= Applicable to properties, list, set, map. Spring Framework :: Merge of collections
40 © Luxoft Training 2012 Spring Framework :: Emply and null properties
41 © Luxoft Training 2012 <beans xmlns=" xmlns:p=" <bean name="p-namespace" class="com.example.ExampleBean" /> <bean name="john-modern" class="com.example.Person" p:name="John Doe" p:spouse-ref="jane" /> Spring Framework :: p-namespace
42 © Luxoft Training 2012 Exercises Develop a simple Spring application