490 likes | 708 Views
An Introduction to Spring. November 21st 2009 Shaun Abram. 1. Agenda. Introduction & Background IoC and Dependency Injection Code Example Spring details Spring MVC. 2. Agenda. Introduction & Background IoC and Dependency Injection Code Example Spring details Spring MVC. 3.
E N D
An Introduction to Spring November 21st 2009 Shaun Abram 1
Agenda Introduction & Background IoC and Dependency Injection Code Example Spring details Spring MVC 2
Agenda Introduction & Background IoC and Dependency Injection Code Example Spring details Spring MVC 3
Introductions Shaun Abram • Sun Certified Enterprise Architect • 10+ years of Java/JEE development • Tech Lead at Wells Fargo • http://www.shaunabram.com You? 4
Spring – Why you should care • Rapidly becoming the de facto standard in enterprise Java • Hugely popular: • 50% of Java shops use Spring • 73% use or planning to use Spring • 9 out of the top 10 global banks use Spring extensively • Used by LinkedIn, Orbitz, Wired, Sky, Accenture, Edmunds.com • Open source projects: Grails • Spring makes JEE development easier Sources: Evans Data Survey Introduction to Spring Framework 2.5 by Rod Johnson 5
A Brief History… …of JavaBeans, Enterprise JavaBeans and Spring. • 1996: Sun released JavaBeans spec • 1998: Sun published EJB 1.0 spec • 2002: “Expert One-on-One J2EE Design and Development” published • 2003: Spring open source project created • 2009: Spring 2.5 latest production release • Spring 3.0 coming soon… 6
Agenda Introduction & Background IoC and Dependency Injection Code Example Spring details Spring MVC 7
IoC and DI Inversion of Control • No longer create/find objects • IoC Container calls your software • Passing it everything it need • aka ‘The Hollywood Principle’ Dependency Injection 8
Dependency Injection at its simplest Dependency Injection enabled //Constructor Injection class Test { Object dependency; public Test(Object dep) { this.dependency = dep; } } //Setter Injection class Test { Object dependency; public setDependency(Object dep) { this.dependency = dep; } } Hard coded dependency class Test { Object dependency; public Test() { dependency = new Object(); } } 9
Agenda Introduction & Background IoC and Dependency Injection Code Example Spring details Spring MVC 10
Example: Account Service Typical Web Architecture: JSP Controller Service DAO (Data Access Object) Database Code to interfaces! 11
Example: AccountService publicinterface AccountService { int getAvailableAmount(int accountNum); } publicclass AccountServiceImpl implements AccountService { AccountDAOaccountDAO = null; public AccountServiceImpl() { accountDAO = new SimpleAccountDAO(); } publicint getAvailableAmount (int accountNum) { Account account = accountDAO.getAccount(accountNum); int availableAmount = account.getBalance() if (availableAmount < 0) availableAmount = 0; return availableAmount; } } 12
Example: AccountDAO publicinterface AccountDAO { Account getAccount(int accountNum); } publicclass SimpleAccountDAO implements AccountDAO { publicAccount getAccount (int accountNum) { Account account = null; //logic to retrieve account using accountNum … return account; } } 13
Example JUnit Test Case public class AccountServiceTest extends TestCase { public void testGetAvailableAmount () { AccountService as = new AccountServiceImpl(); intaccNum = 1; intavailableAmount = as.getAvailableAmount(accNum); assertTrue(availableAmount>=0); } } publicclass AccountServiceImpl implements AccountService { AccountDAO accountDAO = null; public AccountServiceImpl() { accountDAO = new SimpleAccountDAO (); } publicint getAvailableAmount (int accNum) { Account acc = accountDAO.getAccount(accNum); int availableAmount = acc.getBalance(); if (availableAmount < 0) availableAmount = 0; return availableAmount; } } Example: Unit testing issues Issues: • AccountServiceTest indirectly tests SimpleAccountDAO • We are not testing all possibilities Underlying problem is Coupling… 14
Example: Dependency injection enable The AccountServiceImpl is coupled to SimpleAccountDAO Although we are coding to an interface: AccountDAO accountDAO = null; We still directly instantiate a specific implementation: accountDAO = new SimpleAccountDAO (); Solution: Instead of AccountService creating an AccountDAO for itself, Set it up for Dependency Injection Then, could use MOCK implementation of AccountDAO 15
Example: Dependency injection enable Hard coded dependency publicclass AccountServiceImpl { AccountDAOaccountDAO = null; public AccountServiceImpl() { accountDAO = new SimpleAccountDAO (); } publicint getAvailableAmount (int accNum) { … return availableAmount; } } Dependency Injection publicclass AccountServiceImpl { AccountDAOaccountDAO = null; public AccountServiceImpl() { } public void setAccountDAO(AccountDAO accDAO) { this.accountDAO = accDAO; } publicint getAvailableAmount (int accNum) { … return availableAmount; } } 16
public void testGetAvailableAmount () { AccountService accountService= new AccountServiceImpl(); AccountDAO accountDAOMock = mock(AccountDAO.class); accountService.setAccountDAO(accountDAOMock); int accNum = 1; //set Mock behavior here! //execute test Integer availableAmount = accountService.getAvailableAmount(accNum); //verify results assertTrue(availableAmount>=0); } Example: Updated Unit Test • New unit test uses Mock objects • Removes dependency on any specific AccountDAO impl – test focuses on AccountServiceImpl.getAvailableAmount only • We can control what the Mock return allowing us to test all scenarios/branches on AccountServiceImpl.getAvailableAmount • NB AccountService code being used without an IoC container 17
IoC/DI summary Inversion of Control (IoC): • Instead of your code calling a framework, the framework calls your code • The Hollywood principle: Don't call us, we'll call you Dependency Injection (DI): • A flavor of IoC • The framework injects dependent objects With DI, classes • are more loosely coupled • no longer need to create/locate objects • are easier to test • still function perfectly well without an IoC framework! 18
Agenda Introduction & Background IoC and Dependency Injection Code Example Spring details Spring MVC 19
Spring Details: Beans Bean = Spring managed object • Created and managed by the Spring container • Treated in a standard way • creation • initialization • configuration • Life cycle management Spring beans don’t have to be JavaBeans 20
Spring Details - Container A container will • create objects • wire them together • configure them • manage bean lifecycle 2 distinct types: • BeanFactory • ApplicationContext 21
Spring Config File • A Spring IoC container manages one or more beans. • Spring config file contains the bean definitions • The <bean> element is the most basic configuration unit in Spring. e.g. <bean id="accountService" class="com.codecamp.AccountServiceImpl“/> When the Spring container reads this, it will instantiate the accountService bean using the default constructor. Basically, the result is equivalent to accountService= new com.codecamp.AccountServiceImpl(); <bean id=“otherService" class=“com.codecamp.OtherServiceImpl"> <constructor-argvalue=“otherDao"/> <propertyname=“otherDao2"ref=“otherDao2"/> <propertyname="greeting"value="Hello From Spring!"/> </bean> 22
Example: Dependency Injection via Spring • Create a Spring config file • tells Spring what beans to create and what dependencies to inject • ‘Start’ the Spring container • Retrieve first bean 23
Example: Dependency injection via Spring <?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="accountService" class="com.codecamp.AccountServiceImpl"> <constructor-arg ref="accountDao"/> </bean> <bean id="accountDao" class=“com.codecamp.SimpleAccountDao"/> </beans> 24
Spring DI example publicclass SpringExample { publicstaticvoid main(String[] args) { AccountService accountService; int accountNum = new Integer(args[0]); //Spring Bootstrap code FileSystemResource appContext = new FileSystemResource("beans.xml"); BeanFactory factory = new XmlBeanFactory(appContext); accountService = (AccountService)factory.getBean("accountService"); int availableBalance = accountService.getAvailableBalance(accountNum); System.out.println("Your available balance is: " + availableBalance); } } 25
Spring Containers in more detail 2 distinct types: • BeanFactory • ApplicationContext 26
Spring Details - BeanFactory • The simplest of the containers • Provide basic support for DI • An implementation of the Factory design pattern • Creates objects (beans) • Configures objects • Wires objects together • Manages bean lifecycle e.g. org.springframework.beans.factory.xml.XmlBeanFactory 27
Spring Details - ApplicationContext • Build on the notion of a bean factory public interface ApplicationContext extends ListableBeanFactory • Provide application framework service, such as • resolve textual messages from a properties file • including support for Internationalization • event-propagation • publish events to interested event listeners • resource-loading • e.g. • ClassPathXmlApplicationContext • FileSystemXmlApplicationContext • XmlWebApplicationContext 28
Spring Details - Containers ApplicationContext vs BeanFactory? If in doubt, use ApplicationContext 29
Bean scopes So far, we have been using bean definitions like this… <bean id=" greetingDao" class="package.GreetingDao"/> This essentially does the equivalent of greetingDAO = new package.GreetingDao(); But Spring also gives us the ability to control how many instances of a bean are created. This is referred to as the ‘scope’ of the bean. 30
<bean id="accountDao" class="codecamp.AccountDao" scope=”singleton”/> is the same as <bean id=" accountDao " class=" codecamp. AccountDao "/> Singleton scope 31
Other Scopes There are 3 other bean scopes in Spring: • Request • Session • Global session These apply to web aware Spring contexts e.g. Spring MVC, portlets 33
Bean Lifecycle and extension points Lifecycle of a typical Java object (POJO) is very simple: • Create object: Using ‘new’ (or deserialize) • Use object • Once dereferenced – eligible for GC • GC: Object removed from memory Lifecycle of a Spring bean can be much more elaborate: • Instantiate • Populate properties • Custom initialization for beans • Custom destruction for beans 34
Custom Initialization • Custom initialization methods If a bean has a default or custom init method declared, the specified initialization method will be called. <bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/> • InitializingBean interface If the bean implements InitializingBean, it’s afterPropertiesSet() method will be called. Discouraged as couples the code to Spring. Instead, use an initialization method or @PostConstruct • @PostConstruct Not Spring specific – this a JSR-250lifecycle annotation. Used to mark initialization methods that are executed after dependency injection is done but before the object is released for use. Best practice! 35
Custom Destruction • Custom destroy methods Any default or custom destroy method declared will be called. e.g. <bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/> • DisposableBean interface If the bean implements DisposableBean, it’s destroy() method will be called. Discouraged as couples the code to Spring. Instead, use an destroy method or @PreDestroy • @PreDestroy Not Spring specific – this a JSR-250lifecycle annotation. Used on methods as a callback notification to signal that the instance is in the process of being removed by the container. The method annotated with PreDestroy is typically used to release resources that it has been holding. Best practice 36
Benefits of Spring IoC Container Software is • Easier to write • Because you no longer need to worry about object creation and management • Easier to test • Because Spring can easily inject ‘Mock’ objects for testing • Loosely coupled • Objects no longer need to know how to create other objects • Independent of Spring • Use of other frameworks can introduce dependencies • Spring is a non-invasive technology 37
Agenda Introduction & Background IoC and Dependency Injection Code Example Spring details Spring MVC 38
Spring MVC • A web framework providing full MVC implementation • MVC = Model–View–Controller • An architectural pattern that separates business, navigation and presentation logic • View = the user interface elements • Model = data • Controller = the business logic • Spring MVC is Model 2 i.e. it has a dedicated Front Controller (DispatcherServlet)… • Alternative to Struts • Follows Spring paradigms, including IoC/DI 39
Spring MVC Why use Spring MVC? • Designed to be an improvement to Struts • Useful if you are already using Spring • Getting up to speed with Spring MVC may be easier than other web frameworks… • Other Spring beans can be injected into the web controllers • Very testable • e.g. test controllers by using mock services • All parts of the web application can be tested in isolation • Transparently binds request parameters to your business objects • also provides validation and error handling • Provides a useful JSP Tag Library to make data binding with JSPs even easier 40
Spring MVC 41
Example Spring MVC Controller • @Controller • public class HelloWorldController { • @RequestMapping("/helloWorld") • public ModelAndView helloWorld() { • ModelAndView mac = new ModelAndView(); • mav.setViewName("helloWorld"); • mav.addObject("message", "Hello World!"); • return mav; • } • } Spring ‘startup’ code not required because 1) a Listener Servlet called Context Loader will read your Spring config file and load all beans into the container 2) The DispatcherServlet (the Front Controller) passes all requests to the appropriate Controller – no need to manually get access to your first bean (or two).. 42
Spring Web Flow There are 2 kinds of common interaction approaches in web apps 1) Free flow navigation The user controls flow • Conversation flow User has come control, but app controls bigger picture e.g. • ordering a product on a site • login These sequences are called a conversation flow Free flow: Handled by Spring MVC Conversation flow: Handled by Spring Web Flow (a special implementation of a MVC controller) 43
Spring Web Flow Conversation flow can be handled just using Spring MVC e.g. putting links every JSP or Controller But distributing the flow logic throughout the app means: • No central place that specifies the overall flow • Difficult to get an understanding of the overall flow • Difficult to change the flow – requires editing multiple files of multiple types • Difficult to reuse common flows without recoding 44
Spring Web Flow • Captures logical page flows as self-contained modules • Modules are • reusable in different situations • xml files • SWF loosens the coupling between an app's code and its page flow • by enabling you to define the flow in a separate self contained flow definition 45
Spring Summary • All OO software has dependencies on objects • Creating or locating objects can be difficult • Managing dependencies (what software needs what objects) also difficult • Spring provides Dependency Injection (creates objects, injects them where required) • Result is simplified, testable software • There are around 20 Spring modules, including Spring WVC and Web Flow • Spring modules can have widely different purposes • All rely on the core IoC and DI functionality 46
Recommended Reading Spring in Action - Craig Walls The Spring Framework Reference Documentation – springsource.com Expert one-on-one J2EE Design and Development – Rod Johnson Presentation Slides @ www.shaunabram.com 47
Questions? 48
Follow up www.shaunabram.com Shaun@Abram.com 49