Presentation is loading. Please wait.

Presentation is loading. Please wait.

Spring in Action Craig Walls

Similar presentations


Presentation on theme: "Spring in Action Craig Walls"— Presentation transcript:

1 Spring in Action Craig Walls craig@habuma.com
Blog: Wiki:

2 About you… Java? .NET? Ruby/Rails? Who’s using Spring? How long?
Java 6? Java 5? Java 1.4? Java 1.3? 1.2 or older? Who’s using Spring? How long? Spring 1.2? Spring 2? Spring 2.1? Favorite session so far? What brings you to this session?

3 About me Agile developer with Semantra
Natural language business intelligence Developing software professionally for over 13 years Telecom, Finance, Retail, Education Java for most of that Also some C/C++, C#/.NET, Ruby Spring fanatic

4 Who this presentation is for
Spring newbies Crash course in all things Spring Spring experts Lots of familiar material Maybe something you don’t know Some insight into what’s new and coming up in the next versions of Spring

5 What is Spring?

6 Spring is… A POJO container? A lightweight framework? A platform?
A catalyst for change?

7 Spring does… JSF Spring Batch Tapestry OSGi Ruby Web Flow JMX JMS EJB
Caching AJAX Transactions Portlet MVC AOP Security Web MVC Burlap RMI Dependency Injection Hessian XML Groovy HttpInvoker JDBC SOAP JDO Spring-WS JPA Hibernate Rich Client JNDI iBATIS JavaConfig Struts 2/ WebWork 2 Scheduling JCA .NET Struts Spring IDE

8 Spring does… AOP Dependency Injection

9 Dependency Injection

10 DI in a nutshell Without DI, objects get their own dependencies
Directly through construction Through factories With DI, objects are given their dependencies Through constructors Through setter methods Indirectly through method replacement DI + interfaces = loosely coupled objects

11 Knights and Quests Imagine a ValiantKnight that embarks on quests
A ValiantKnight needs a Quest Quest is an interface: public interface Quest { void embark(); }

12 What’s wrong with this? public class ValiantKnight {
public void embarkOnQuest() { Quest quest = new SlayDragonQuest(); quest.embark(); }

13 How about this? public class ValiantKnight{
public void embarkOnQuest() { Quest quest = QuestFactory. getInstance().getQuest(); quest.embark(); }

14 Is this any better? public class ValiantKnight {
public void embarkOnQuest() { InitialContext ctx = null; try { ctx = new InitialContext(); Quest quest = (Quest) ctx.lookup( "java:comp/env/Quest"); quest.embark(); } catch (NamingException e) { } finally { if(ctx != null) { try {ctx.close(); } catch (Exception e) {} }

15 Let’s try this… public class ValiantKnight { private Quest quest;
public ValiantKnight(Quest quest) { this.quest = quest; } public void embarkOnQuest() { quest.embark();

16 Or perhaps… public class ValiantKnight { private Quest quest;
public ValiantKnight() {} public void setQuest(Quest quest) { this.quest = quest; } public void embarkOnQuest() { quest.embark(); Where does Quest come from? How is it Implemented?

17 Wiring in Spring (constructor)
<bean id="knight" class="com.springinaction.ValiantKnight"> <constructor-arg ref="quest" /> </bean> <bean id="quest" class="com.springinaction.SlayDragonQuest" />

18 Wiring in Spring (setter)
<bean id="knight" class="com.springinaction.ValiantKnight"> <property name="quest" ref="quest" /> </bean> <bean id="quest" class="com.springinaction.SlayDragonQuest" />

19 Wiring in Spring 2.5 (annotations)
@Component public class ValiantKnight { @Autowired private Quest quest; public ValiantKnight() {} public void embarkOnQuest() { quest.embark(); }

20 Aspect-Oriented Programming

21 AOP in a nutshell Aspects decouple “concerns” from the objects that they apply to Common examples: Logging, caching, security, transactions Imagine a Minstrel class that chronicles a Knight’s exploits in song…

22 Without AOP Is this really the knight’s job?
public void embarkOnQuest() { minstrel.sing( "Fa la la, the knight is so brave!"); quest.embark(); "He did embark on a noble quest!"); } Is this really the knight’s job?

23 With AOP public void embarkOnQuest() { quest.embark(); }
Where’s the Minstrel?

24 Minstrel.java public class Minstrel { public void singBefore() {
System.out.println( "Fa la la, the knight is so brave!"); } public void singAfter() { "He did embark on a noble quest!");

25 Weaving aspects in Spring
<bean id="minstrel" class="com.springinaction.Minstrel" /> <aop:config> <aop:aspect ref="minstrel"> <aop:pointcut id="embarkment" expression="execution(* *.embarkOnQuest(..))" /> <aop:before method="singBefore" pointcut-ref="embarkment" /> <aop:after-returning method="singAfter" </aop:aspect> </aop:config>

26 Using @AspectJ @Aspect public class Minstrel {
@Pointcut("execution(* *.embarkOnQuest(..))") public void embarkment() {} @Before("embarkment()") public void singBefore() { System.out.println( "Fa la la, the knight is so brave!"); } @After("embarkment()") public void singAfter() { "He did embark on a noble quest!");

27 In Spring XML… <aop:aspectj-autoproxy /> Yep…that’s it

28 DI meets AOP @Configurable enables injection into objects not managed by Spring Domain objects, for example Configure in Spring XML: Spring 2.0: <aop:spring-configured/> Spring 2.1: <context:spring-configured/> Needs a load-time-weaver: Spring 2.0: -javaagent:/path/to/aspect-weaver.jar Spring 2.1…two options: -javaagent:/path/to/spring-agent.jar <context:load-time-weaver />

29 Spring and JDBC

30 Conventional JDBC Déjà vu? What do you intend to do about this???
Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = dataSource.getConnection(); stmt = conn.prepareStatement(”select id, first_name, last_name from Employee where id=?"); stmt.setInt(1, id); rs.stmt.executeQuery(); Employee employee = null; if(rs.next()) { employee = new Employee(); employee.setId(rs.getInt(1)); employee.setFirstName(rs.getString(2)); employee.setLastName(rs.getString(3)); } return employee; } catch (SQLException e) { } finally { if(rs ! null) { rs.close(); } if(stmt != null) { stmt.close(); } if(conn != null) { conn.close(); } } catch (SQLException e) {} Déjà vu? What do you intend to do about this???

31 SQLException The case of the ambiguous and useless checked exception…
SQLException means that something went wrong with the database…but what? The types of problems that SQLException represent are usually not runtime- addressable. What can you do in a catch block to handle a column not found error?

32 Spring’s DataAccessException
CannotAcquireLockException CannotSerializeTransactionException CleanupFailureDataAccessException ConcurrencyFailureException DataAccessException DataAccessResourceFailureException DataIntegrityViolationException DataRetrievalFailureException DeadlockLoserDataAccesException EmptyResultDataAccessException IncorrectResultSizeDataAccessException IncorrectUpdateSemanticsDataAccessException InvalidDataAccessApiUsageException InvalidDataAccessResourceUsageException OptimisticLockingFailureException PermissionDeniedDataAccessException PessimisticLockingFailureException TypeMismatchDataAccessException UncategorizedDataAccessException

33 JDBC: Spring-style Notice no awkward try/catch block And no JDBC
List matches = jdbcTemplate.query( "select id, first_name, last_name from Employee" + " where id=?", new Object[] {Long.valueOf(id)}, new RowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException, DataAccessException { Employee employee = new Employee(); employee.setId(rs.getInt(1)); employee.setFirstName(rs.getString(2)); employee.setLastName(rs.getString(3)); return employee; } }); return matches.size() > 0 ? (Employee) matches.get(0) : null; Notice no awkward try/catch block And no JDBC boilerplate

34 JDBC Template <bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource" > <property name="driverClassName” value="org.hsqldb.jdbcDriver" /> <property name="url" value="jdbc:hsqldb:hsql://localhost/employee/employee" /> <property name="username" value="sa" /> <property name="password" value="" /> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" > <property name="dataSource" ref="dataSource" /> <bean id="employeeDao" class="com.springinaction.JdbcEmployeeDao"> <property name="jdbcTemplate" ref="jdbcTemplate" />

35 JDBC: Spring 2 and Java 5 Uses generics No need to wrap No need to
List<Employee> matches = simpleJdbcTemplate.query( "select id, first_name, last_name from Employee" + " where id=?", new ParameterizedRowMapper<Employee>() { public Employee mapRow(ResultSet rs, int rowNum) throws SQLException { Employee employee = new Employee(); employee.setId(rs.getInt(1)); employee.setFirstName(rs.getString(2)); employee.setLastName(rs.getString(3)); return employee; } }, id); return matches.size() > 0 ? matches.get(0) : null; Uses generics No need to wrap parameters No need to cast result

36 One more thing on templates
JDBC isn’t the only place where Spring provides templates… Hibernate JPA JDO TopLink iBATIS JCA JMS JNDI

37 Declarative Transactions

38 EJB’s killer feature… …now available in convenient POJO form.
Spring uses AOP to enable declarative transactions on POJO methods In some ways, even more capable than EJB transactions (more propagation options, isolation levels…)

39 Spring 2 declarative tx <tx:advice id="txAdvice">
<tx:attributes> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="*" propagation="SUPPORTS" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* *..EmployeeService.*(..))" /> </aop:config>

40 Spring 2 + Java 5 transactions
In service class: @Transactional(propagation=Propagation.SUPPORTS, readOnly=true) public class EmployeeServiceImpl implements EmployeeService { @Transactional(propagation=Propagation.REQUIRED, readOnly=false) public void addEmployee(Employee rant) { } In Spring XML: <tx:annotation-driven />

41 Spring MVC

42 Why Spring MVC? Spring usually doesn’t reinvent the wheel…
No persistence framework At one time, Struts was only option And not necessarily a good option Spring MVC reinvented the MVC wheel…addressing the shortcomings of Struts

43 Struts 1.x Action public class DisplayCustomerAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { CustomerDetailForm cdf = (CustomerDetailForm) form; Customer customer = lookupCustomer(cdf.getAccountNumber()); request.setAttribute("customer", customer); return mapping.findForward("customerDetail"); }

44 Spring MVC Controller public class DisplayCustomerController
extends AbstractController { protected ModelAndView handleRequestInternal( HttpServletRequest req, HttpServletResponse response) throws Exception { long customerId = Long.valueOf(req.getParameter("id")); Customer customer = lookupCustomer(customerId); return new ModelAndView( "customerDetail", customer); }

45 Mapping URLs to controllers
SimpleUrlHandlerMapping: <bean id="urlMapping" class="org.springframework.web.servlet.handler. SimpleUrlHandlerMapping"> <property name="mappings"> <value> /home.htm=homeController /login.htm=loginController /addSpittle.htm=addSpittleController /addSpitter.htm=addSpitterController </value> </property> </bean>

46 Auto-mapping of controllers
ControllerClassNameHandlerMapping: <bean id="urlMapping" class="org.springframework.web.servlet.mvc.support. ControllerClassNameHandlerMapping" /> /home.htm HomeController /login.htm LoginController /addspittle.htm AddSpittleController

47 Mapping view names to views
InternalResourceViewResolver: <bean id="jspViewResolver" class="org.springframework.web.servlet.view. InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> “home” /WEB-INF/jsp/home.jsp “login” /WEB-INF/jsp/login.jsp “orderForm” /WEB-INF/jsp/orderForm.jsp

48 The Struts 1.x Action selection

49 Spring Controller Selection

50 Spring 2.5 Controllers Annotated with @Controller
So that <context:component-scan> can find and register them Also annotated To map requests to handler methods Optionally annotated Transparently stores model attributes in session Parameters can be mapped To automatically map request parameters to handler method parameters. Parameters can also be mapped Maps a model attribute to a method parameter @ModelAttribute can also be applied to methods To populate the model with the output from the method

51 Minimal XML needed for MVC
<context:component-scan base-package="com.habuma.spitter.mvc" /> <bean class="org.springframework.web.servlet. mvc.annotation. AnnotationMethodHandlerAdapter" /> Auto-register all classes in com.habuma.spitter.mvc package Map beans

52 Annotated controller example
@RequestMapping("/editPet.do") @SessionAttributes("pet") public class EditPetForm { @ModelAttribute("types") public Collection<PetType> populatePetTypes() { return this.clinic.getPetTypes(); } @RequestMapping(type = "POST") public String Pet pet, BindingResult result, SessionStatus status) { new PetValidator().validate(pet, result); if (result.hasErrors()) { return "petForm"; } else { this.clinic.storePet(pet); status.setComplete(); return "redirect:owner.do?ownerId=" + pet.getOwner().getId(); }

53 Annotated controller (2)
@RequestMapping("/editPet.do") @SessionAttributes("pet") public class EditPetForm { @RequestMapping(type = "GET") public String setupForm( @RequestParam("petId") int petId, ModelMap model) { Pet pet = this.clinic.loadPet(petId); model.addAttribute("pet", pet); return "petForm"; }

54 What about…??? Struts 2/WebWork 2? JSF? Tapestry? Wicket? Seam?
Grails? The billions of other MVC frameworks

55 What’s new in Spring 2 New/extensible configuration namespaces
Easier AOP and support Easier transactions Injection into objects not managed by Spring Support for JPA Asynchronous JMS support New JDBC templates (Java 5 and named parameters) New form-binding JSP tag library Portlet MVC Dynamic language beans (JRuby, Groovy, BeanShell) JMX: Notifications and registration control Convention over configuration improvements

56 What’s coming in Spring 2.5
JMS configuration namespace Context configuration namespace <aop:spring-configured> moves to <context:spring-configured> Annotation-driven configuration @RequestParam Autodetected components Requires JDK 1.4 or higher Named parameters added to SimpleJdbcTemplate ParameterizedBeanPropertyRowMapper for automatically mapping between columns and bean properties <context:load-time-weaver/> : Spring configured load time weaving Hibernate 2.1 support goes away JUnit 4.x support (SpringJUnit4ClassRunner)

57 Don’t forget to turn in evals!!!
Q & A Don’t forget to turn in evals!!!


Download ppt "Spring in Action Craig Walls"

Similar presentations


Ads by Google