A Walking Tour of (almost) all of Springdom
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

A Walking Tour of (almost) all of Springdom

on

  • 2,992 views

this is the deck for my 3+ hour walking tour talk that I give as a workshop at various conferences. This talk introduces practically everything in Spring -- come into the talk unaware of the concepts ...

this is the deck for my 3+ hour walking tour talk that I give as a workshop at various conferences. This talk introduces practically everything in Spring -- come into the talk unaware of the concepts or frameworks and leave with a working knowledge of all the frameworks, and of all the applications for the technologies.

Statistics

Views

Total Views
2,992
Views on SlideShare
2,990
Embed Views
2

Actions

Likes
10
Downloads
160
Comments
1

2 Embeds 2

http://www.slashdocs.com 1
https://www.docsnode.com 1

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • On slide 225 there's a broken link: 'github.com/SpringSource/html5expenses' should be 'github.com/SpringSource/html5expense', without the final 's'
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n\n
  • Hello, thank you or having me. Im pleased to have the opportunity to introduce you today to Spring and the SpringSource Tool Suite \n\nMy anem is Josh Long. I serve as the developer advocate for the Spring framework. I’ve used it in earnest and advocated it for many years now. i’m an author on 3 books on the technology, as well as a comitter to many of the Spring projects. Additionally, I take community activism very seriously and do my best to participate in the community. Sometimes this means answering question on Twitter, or in the forums, or helping contribute to the InfoQ.com and Artima.com communities\n
  • \n
  • \n
  • \n
  • these different framerworks let u tackle any problem youre likely to want to solve today \n- we support javee1.4 + 1.5 + 1.6; \n\nsits above target platform \nruns in cloud \n\n
  • \n
  • there are lots of frameworks to solve lots of problems\nthey all use the same pojo metaphor\nlets review some ofthem ... \nnaturally, the best part is that you can pick and choose - architecture a la carte! these are just lbiraris you can add to your applications, after all \n
  • this is the heart of Spring, and DI and IOC. the rest is learning about application of DI/IOC\n
  • this is the heart of Spring, and DI and IOC. the rest is learning about application of DI/IOC\n
  • this is the heart of Spring, and DI and IOC. the rest is learning about application of DI/IOC\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • the toolchain is STS, java compiler (no startup scripts required!) \nintroduce Spring Roo\nintroduce the Appcontexts\nintroduce the various Di configuration types \n\n
  • \n
  • Spring has the world view of all the objects in your object graph, and it gives you full control over that world viw\n\nYou can intercept object creation and prescribe changes to how things are built\n\nyou have low level mechanisms like BPPs and BFPPs which allow you to veto, override or merely observe the creation of objects\n\nu have AOP to lalow u to treat things like mehtod invocation as events\n
  • the toolchain is STS, java compiler (no startup scripts required!) \nintroduce Spring Roo\nintroduce the Appcontexts\nintroduce the various Di configuration types \n\n
  • \n
  • this is the heart of Spring, and DI and IOC. the rest is learning about application of DI/IOC\n
  • this is the heart of Spring, and DI and IOC. the rest is learning about application of DI/IOC\n
  • this is the heart of Spring, and DI and IOC. the rest is learning about application of DI/IOC\n
  • the toolchain is STS, java compiler (no startup scripts required!) \nintroduce Spring Roo\nintroduce the Appcontexts\nintroduce the various Di configuration types \n\n
  • \n
  • sometims, there are values that u cant get at using the main 3 types\n\nor, sometimes you have an object whose creation needs to be a) resuable and b) dynamic, based on permutations of certain dependencies. \n
  • this is the heart of Spring, and DI and IOC. the rest is learning about application of DI/IOC\n
  • this is the heart of Spring, and DI and IOC. the rest is learning about application of DI/IOC\n
  • this is the heart of Spring, and DI and IOC. the rest is learning about application of DI/IOC\n
  • \n\n
  • \n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • this is the heart of Spring, and DI and IOC. the rest is learning about application of DI/IOC\n
  • \n\n
  • \n
  • \n
  • \n\n
  • \n
  • \n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • Example of what can happen if you run processes more than correct number of times.\n
  • A better approach is decompose the war into a set of services.\nYou can do that either by nouns or by verbs.\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • One very popular open-source, message broker is RabbitMQ.\nIt designed to be robust, have high performance and be easy to use.\n\n
  • An interesting feature of RabbitMQ is that it implements a standard messaging protocol called AMQP.\nThis is quite different than JMS where each JMS implementation had its own java client libraries.\nAMQP is an efficient wire level protocol and is supported by multiple message brokers.\nThere are clients in multiple languages.\n\n
  • \n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • The AMQP messaging model is a little different to JMS, for example.\n\nProducers write a message to an exchange\nConsumers read from a queue that is bound to exchange.\n\nWhether a message written to an exchange ends up in queue depends on the type of the exchange.\nThere are a few different types of exchange.\n\nOne standard type is the fanout exchange.\nA fanout exchange writes a message to all of the queues that are bound to it.\n\n
  • There is also a direct exchange.\nProducers write a message along with a routing key.\nQueues are bound to the exchange with a binding.\nif a message’s routing key matches the binding then the message is written to that queue.\n\n
  • There is also a direct exchange.\nProducers write a message along with a routing key.\nQueues are bound to the exchange with a binding.\nif a message’s routing key matches the binding then the message is written to that queue.\n\n
  • There is also a direct exchange.\nProducers write a message along with a routing key.\nQueues are bound to the exchange with a binding.\nif a message’s routing key matches the binding then the message is written to that queue.\n\n
  • There is also a direct exchange.\nProducers write a message along with a routing key.\nQueues are bound to the exchange with a binding.\nif a message’s routing key matches the binding then the message is written to that queue.\n\n
  • There is also a direct exchange.\nProducers write a message along with a routing key.\nQueues are bound to the exchange with a binding.\nif a message’s routing key matches the binding then the message is written to that queue.\n\n
  • There is also a direct exchange.\nProducers write a message along with a routing key.\nQueues are bound to the exchange with a binding.\nif a message’s routing key matches the binding then the message is written to that queue.\n\n
  • There is also a direct exchange.\nProducers write a message along with a routing key.\nQueues are bound to the exchange with a binding.\nif a message’s routing key matches the binding then the message is written to that queue.\n\n
  • There is also a direct exchange.\nProducers write a message along with a routing key.\nQueues are bound to the exchange with a binding.\nif a message’s routing key matches the binding then the message is written to that queue.\n\n
  • There is also a direct exchange.\nProducers write a message along with a routing key.\nQueues are bound to the exchange with a binding.\nif a message’s routing key matches the binding then the message is written to that queue.\n\n
  • There is also a direct exchange.\nProducers write a message along with a routing key.\nQueues are bound to the exchange with a binding.\nif a message’s routing key matches the binding then the message is written to that queue.\n\n
  • There is also a direct exchange.\nProducers write a message along with a routing key.\nQueues are bound to the exchange with a binding.\nif a message’s routing key matches the binding then the message is written to that queue.\n\n
  • There are also topic exchanges, which basically implement pub/sub.\nHere the binding is can contain wildcards that are used to match against the message’s routing key\n
  • There are also topic exchanges, which basically implement pub/sub.\nHere the binding is can contain wildcards that are used to match against the message’s routing key\n
  • There are also topic exchanges, which basically implement pub/sub.\nHere the binding is can contain wildcards that are used to match against the message’s routing key\n
  • There are also topic exchanges, which basically implement pub/sub.\nHere the binding is can contain wildcards that are used to match against the message’s routing key\n
  • There are also topic exchanges, which basically implement pub/sub.\nHere the binding is can contain wildcards that are used to match against the message’s routing key\n
  • There are also topic exchanges, which basically implement pub/sub.\nHere the binding is can contain wildcards that are used to match against the message’s routing key\n
  • There are also topic exchanges, which basically implement pub/sub.\nHere the binding is can contain wildcards that are used to match against the message’s routing key\n
  • There are also topic exchanges, which basically implement pub/sub.\nHere the binding is can contain wildcards that are used to match against the message’s routing key\n
  • There are also topic exchanges, which basically implement pub/sub.\nHere the binding is can contain wildcards that are used to match against the message’s routing key\n
  • There are also topic exchanges, which basically implement pub/sub.\nHere the binding is can contain wildcards that are used to match against the message’s routing key\n
  • There are also topic exchanges, which basically implement pub/sub.\nHere the binding is can contain wildcards that are used to match against the message’s routing key\n
  • There are also topic exchanges, which basically implement pub/sub.\nHere the binding is can contain wildcards that are used to match against the message’s routing key\n
  • Spring AMQP is a project, which provides wrapper classes that simplify the development of messaging applications.\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • Familiar to somebody who’s used Struts:\n Models (like Struts ActionForms)\n Views (like Struts views: tiles, .jsp(x)s, velocity, PDF, Excel, etc.) \n Controllers (like Struts Actions)\n\n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pieces are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • another example of the fact that often the client side model won’t represent the server side model \n\n
  • \n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • another example of the fact that often the client side model won’t represent the server side model \n\n
  • talk about how convenient the messaging support is, then roll back and start looking at how u might do the same thing manually. Explain that many of the pices are already there, and then seguqe into a discussion about the core Spring APIs. Lets imagine we’re going to build ourselves a file system poller to notify us of when something’s happened on the file system\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

A Walking Tour of (almost) all of Springdom Presentation Transcript

  • 1. A Walking Tour of SpringJosh LongSpring Developer AdvocateSpringSource, a Division of VMwarehttp://www.joshlong.com || @starbuxman || josh.long@springsource.com © 2009 VMware Inc. All rights reserved
  • 2. About SpringSource is the organization that develops the Spring framework, the leading enterprise Java framework SpringSource was acquired by VMware in 2009 VMware and SpringSource bring you to the cloud and deliver on the mission of “build, run, manage” • established partnerships with the major players in the business, including Adobe, SalesForce, and Google to help deliver the best experience for Spring users across multiple platforms Leading contributor to projects like Apache HTTPD and Apache Tomcat 2
  • 3. About Josh LongSpring Developer Advocatetwitter: @starbuxmanjosh.long@springsource.com 3
  • 4. SPRING: a WALKING TOURIntroduction 4
  • 5. Why Are We Here? “ Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. ” -Bob Martin 5
  • 6. Why Are We Here? do NOT reinvent the Wheel! 6
  • 7. Spring’s aim: bring simplicity to java development data web tier batch integration & access & service tier mobile processing messaging / NoSQL / RIA Big Data The Spring frameworkthe cloud: lightweight traditional WebSphere CloudFoundry tc Server JBoss AS Google App Engine Tomcat WebLogic Amazon BeanStalk Jetty (on legacy versions, too!) 7
  • 8. Not All Sides Are Equal 8
  • 9. The Spring Framework Framework Description Spring Core The foundation Spring @MVC the web leading framework (comes with the core framework) Spring Security Extensible framework providing authentication, authorization Spring Webflow An excellent web framework for building multi-page flows Spring Web Services Contract-first, document–centric SOAP and XML web services Spring Batch Powerful batch processing framework Spring Integration Implements enterprise integration patterns Spring BlazeDS Support for Adobe BlazeDS Spring AMQP interface with AMQP message brokers, like RabbitMQ Spring Data NoSQL options: HBase, MongoDB, Redis, Riak, CouchDB, Neo4J, etc. Spring Social integrate Twitter, Facebook, Tripit, MySpace, LinkedIn, etc. Spring Hadoop Provides a POJO-centric approach to building Hadoop applications provides first-class support for service Spring Mobile, Spring Android creation and consumption for iPhone, Android Spring GemFire Provides the easiest interface for the GemFire enterprise data grid technology 9
  • 10. The Spring ApplicationContext Spring Manages the beans you tell it to manage (Implicitly, Explicitly) • use annotations (JSR 250, JSR 330, native) • XML • Java configuration • component scanning You can of course use all of them! Mix ‘n match All configuration styles tell the ApplicationContext how to manage your beans 10
  • 11. The Spring ApplicationContext Annotations (component-scanning) • best when you want Spring to sort it all out in the wash, no need for explicit configuration Java Configuration • type-safe, and explicit - all configuration is centralized. Provides a good birds-eye view of your application XML • explicit - namespaces still provide the most punch in a lot of cases All together • use Java configuration for your regular third party beans (like a DataSource) • XML namespaces for DSLs and higher level functionality (Spring Integration, Batch, etc.) • annotations for your components (a @Service, or a Spring MVC @Controller) 11
  • 12. The Spring ApplicationContextpublic class Main { public static void main(String [] args) throws Throwable { ApplicationContext ctx = new AnnotationConfigApplicationContext( ServicesConfiguration.class ); CustomerService serviceReference = ctx.getBean( CustomerService.class ); Customer customer = serviceReference.createCustomer( "Juergen", "Hoeller"); }} 12
  • 13. Spring Makes Building Applications Easy... Not confidential. Tell everyone. 13
  • 14. I want Database Access ... with Hibernate 4 Support @Service public class CustomerService { public Customer createCustomer(String firstName, String lastName, Date signupDate) { ... } } Not confidential. Tell everyone. 14
  • 15. I want Database Access ... with Hibernate 4 Support @Service public class CustomerService { @Inject private SessionFactory sessionFactory; public Customer createCustomer(String firstName, String lastName, Date signupDate) { Customer customer = new Customer(); customer.setFirstName(firstName); customer.setLastName(lastName); customer.setSignupDate(signupDate); sessionFactory.getCurrentSession().save(customer); return customer; } } Not confidential. Tell everyone. 15
  • 16. I want Database Access ... with Hibernate 4 Support @Service public class CustomerService { @Inject private SessionFactory sessionFactory; @Transactional public Customer createCustomer(String firstName, String lastName, Date signupDate) { Customer customer = new Customer(); customer.setFirstName(firstName); customer.setLastName(lastName); customer.setSignupDate(signupDate); sessionFactory.getCurrentSession().save(customer); return customer; } } Not confidential. Tell everyone. 16
  • 17. I want Declarative Cache Management... @Service public class CustomerService { @Inject private SessionFactory sessionFactory; @Transactional @Cacheable(“customers”) public Customer createCustomer(String firstName, String lastName, Date signupDate) { Customer customer = new Customer(); customer.setFirstName(firstName); customer.setLastName(lastName); customer.setSignupDate(signupDate); sessionFactory.getCurrentSession().save(customer); return customer; } } Not confidential. Tell everyone. 17
  • 18. I want a RESTful Endpoint... package org.springsource.examples.spring31.web; .. @Controller public class CustomerController { @Inject private CustomerService customerService; @RequestMapping(value = "/customer/{id}", produces = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody Customer customerById(@PathVariable("id") Integer id) { return customerService.getCustomerById(id); } ... } Not confidential. Tell everyone. 18
  • 19. DEMO• the 80% case! Not confidential. Tell everyone.
  • 20. ...But Where’d the SessionFactory come from? Not confidential. Tell everyone. 20
  • 21. A Quick Primer on Configuration in Spring 3.1 ....<beans><tx:annotation-driven transaction-manager = "txManager" /><context:component-scan base-package = "org.springsource.examples.spring31.services" /><context:property-placeholder properties = "config.properties" /><bean id = "txManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name = "sessionFactory" ref = "sessionFactory" /></bean> <bean id = "sessionFactory" class = "org.springframework.orm.hibernate4.LocalSessionFactoryBean"> ... </bean></beans> Not confidential. Tell everyone.
  • 22. A Quick Primer on Configuration in Spring 3.1 ....<beans><tx:annotation-driven transaction-manager = "txManager" /><context:component-scan base-package = "org.springsource.examples.spring31.services" /><context:property-placeholder properties = "config.properties" /><bean id = "txManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name = "sessionFactory" ref = "sessionFactory" /></bean> <bean id = "sessionFactory" class = "org.springframework.orm.hibernate4.LocalSessionFactoryBean"> ... </bean></beans> Not confidential. Tell everyone.
  • 23. A Quick Primer on Configuration in Spring 3.1@Configuration@PropertySource("/config.properties")@EnableTransactionManagement@ComponentScan(basePackageClasses = {CustomerService.class})public class ServicesConfiguration { @Bean public PlatformTransactionManager txManager() throws Exception { return new HibernateTransactionManager(this.sessionFactory()); } @Bean public SessionFactory sessionFactory() { ... }} Not confidential. Tell everyone.
  • 24. A Quick Primer on Configuration in Spring 3.1 ....<beans><tx:annotation-driven transaction-manager = "txManager" /><context:component-scan base-package = "org.springsource.examples.spring31.services" /><context:property-placeholder properties = "config.properties" /><bean id = "txManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name = "sessionFactory" ref = "sessionFactory" /></bean> <bean id = "sessionFactory" class = "org.springframework.orm.hibernate4.LocalSessionFactoryBean"> ... </bean></beans> Not confidential. Tell everyone.
  • 25. A Quick Primer on Configuration in Spring 3.1@Configuration@PropertySource("/config.properties")@EnableTransactionManagement@ComponentScan(basePackageClasses = {CustomerService.class})public class ServicesConfiguration { @Bean public PlatformTransactionManager txManager() throws Exception { return new HibernateTransactionManager(this.sessionFactory()); } @Bean public SessionFactory sessionFactory() { ... }} Not confidential. Tell everyone.
  • 26. A Quick Primer on Configuration in Spring 3.1 ....<beans><tx:annotation-driven transaction-manager = "txManager" /><context:component-scan base-package = "org.springsource.examples.spring31.services" /><context:property-placeholder properties = "config.properties" /><bean id = "txManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name = "sessionFactory" ref = "sessionFactory" /></bean> <bean id = "sessionFactory" class = "org.springframework.orm.hibernate4.LocalSessionFactoryBean"> ... </bean></beans> Not confidential. Tell everyone.
  • 27. A Quick Primer on Configuration in Spring 3.1@Configuration@PropertySource("/config.properties")@EnableTransactionManagement@ComponentScan(basePackageClasses = {CustomerService.class})public class ServicesConfiguration { @Bean public PlatformTransactionManager txManager() throws Exception { return new HibernateTransactionManager(this.sessionFactory()); } @Bean public SessionFactory sessionFactory() { ... }} Not confidential. Tell everyone.
  • 28. A Quick Primer on Configuration in Spring 3.1 ....<beans><tx:annotation-driven transaction-manager = "txManager" /><context:component-scan base-package = "org.springsource.examples.spring31.services" /><context:property-placeholder properties = "config.properties" /><bean id = "txManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name = "sessionFactory" ref = "sessionFactory" /></bean> <bean id = "sessionFactory" class = "org.springframework.orm.hibernate4.LocalSessionFactoryBean"> ... </bean></beans> Not confidential. Tell everyone.
  • 29. A Quick Primer on Configuration in Spring 3.1@Configuration@PropertySource("/config.properties")@EnableTransactionManagement@ComponentScan(basePackageClasses = {CustomerService.class})public class ServicesConfiguration { @Bean public PlatformTransactionManager txManager() throws Exception { return new HibernateTransactionManager(this.sessionFactory()); } @Bean public SessionFactory sessionFactory() { ... }} Not confidential. Tell everyone.
  • 30. A Quick Primer on Configuration in Spring 3.1 ....<beans><tx:annotation-driven transaction-manager = "txManager" /><context:component-scan base-package = "org.springsource.examples.spring31.services" /><context:property-placeholder properties = "config.properties" /><bean id = "txManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name = "sessionFactory" ref = "sessionFactory" /></bean> <bean id = "sessionFactory" class = "org.springframework.orm.hibernate4.LocalSessionFactoryBean"> ... </bean></beans> Not confidential. Tell everyone.
  • 31. A Quick Primer on Configuration in Spring 3.1@Configuration@PropertySource("/config.properties")@EnableTransactionManagement@ComponentScan(basePackageClasses = {CustomerService.class})public class ServicesConfiguration { @Bean public PlatformTransactionManager txManager() throws Exception { return new HibernateTransactionManager(this.sessionFactory()); } @Bean public SessionFactory sessionFactory() { ... }} Not confidential. Tell everyone.
  • 32. A Quick Primer on Configuration in Spring 3.1 ....<beans><tx:annotation-driven transaction-manager = "txManager" /><context:component-scan base-package = "org.springsource.examples.spring31.services" /><context:property-placeholder properties = "config.properties" /><bean id = "txManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name = "sessionFactory" ref = "sessionFactory" /></bean> <bean id = "sessionFactory" class = "org.springframework.orm.hibernate4.LocalSessionFactoryBean"> ... </bean></beans> Not confidential. Tell everyone.
  • 33. A Quick Primer on Configuration in Spring 3.1@Configuration@PropertySource("/config.properties")@EnableTransactionManagement@ComponentScan(basePackageClasses = {CustomerService.class})public class ServicesConfiguration { @Bean public PlatformTransactionManager txManager() throws Exception { return new HibernateTransactionManager(this.sessionFactory()); } @Bean public SessionFactory sessionFactory() { ... }} Not confidential. Tell everyone.
  • 34. DEMO introduce the tool chain how to “setup” Spring basic dependency injection • annotations (JSR 250, JSR 330, native) • xml • java configuration Not confidential. Tell everyone. 34
  • 35. Working with many beans Not confidential. Tell everyone. 35
  • 36. Working with many beans Low Level • BeanPostProcessor • BeanFactoryPostProcessor Higher Level • AOP Not confidential. Tell everyone. 36
  • 37. DEMO Demos: • Bean*PostProcessor • AspectJ Not confidential. Tell everyone. 37
  • 38. The Life of a Bean Not confidential. Tell everyone. 38
  • 39. Life Cycles Life Cycles for different folks • “safe and consistent” - use the interfaces • InitializingBean, DisposableBean • correspond to init-method and destroy-method attributes • Simple and component-centric : use the annotations • @PostConstruct, @PreDestroy • correspond to init-method and destroy-method attributes • More power: SmartLifecycle • gives you the ability to dynamically start and stop beans in a certain order as well as to query whether the bean’s been started or not. Not confidential. Tell everyone. 39
  • 40. Scopes Spring beans have scopes • default: singleton • can be: • prototype • HTTP session • HTTP request • HTTP application (servlet, basically) • “step” in Spring batch • thread-local • Spring Web Flow “flow” scoped • Spring Web Flow “conversation scoped” • Spring Web Flow “view” scoped (in JSF) • Activiti BPMN2 process-scoped Not confidential. Tell everyone. 40
  • 41. Scopes • Implement o.s.beans.factory.config.Scope • register the scope with a o.s.beans.factory.config.CustomScopeConfigurerpublic interface Scope { Object get(String name, ObjectFactory<?> objectFactory); map-like lookup of beans in a given Object remove(String name); scope void registerDestructionCallback(String name, Runnable callback); well known beans like the Object resolveContextualObject(String key); HttpServletRequest ‘request’ for ‘request’ scope String getConversationId();} null, or storage specific ‘conversation’ ID Not confidential. Tell everyone. 41
  • 42. DEMO Demos: • life cycle callbacks • scopes • using • creating your own Not confidential. Tell everyone. 42
  • 43. Getting Beans from Strange Places Not confidential. Tell everyone. 43
  • 44. Getting Beans from Strange Places FactoryBeans Spring Expression Language • convenient way to get at values and inject them Spring environment specific beans (profiles) • introduced in Spring 3.1 • make it easy to conditionally define an object based on some sort of runtime condition Not confidential. Tell everyone. 44
  • 45. Getting Beans from Strange Places FactoryBeans • interface that’s used to provide a reusable definition of how to create a complicated object with many dependencies • Related: Java configuration, and builders • prefer both over FactoryBeans where possible Not confidential. Tell everyone. 45
  • 46. Getting Beans from Strange Places Spring Expression Language • convenient way to get at values and inject them • Andy Clement’s a genius • like the Unified JSF EL, on steroids • Can be used in Java, XML • @Value(“#{ ... }”) or value = “#{ .. }” Not confidential. Tell everyone. 46
  • 47. Getting Beans from Strange Places Spring profiles • @Profile(“production”) @Configuration ... • <beans profile = ‘production’> ... </beans> • Use System properties or simply specify the active profile on the environment • Use ApplicationContextInitializer in web applications Not confidential. Tell everyone. 47
  • 48. Getting Beans from Strange Places ... <beans ....> In Development = “default”> <beans profile <ds:embedded-database id= "dataSource" type = “H2” /> </beans> <beans profile = “cloud”> In Production <cloud:data-source id="dataSource"/> </beans> </beans> Not confidential. Tell everyone. 48
  • 49. Getting Beans from Strange Places ... <beans ....> <beans profile = “dev”> <ds:embedded-database id= "dataSource" type = “H2” /> </beans> <beans profile = “cloud”> <cloud:data-source id="dataSource"/> </beans> </beans> Not confidential. Tell everyone. 49
  • 50. Environment Configuration Not confidential. Tell everyone. 50
  • 51. Environment Configuration Associating specific bean definitions with specific environments • XML profile attribute on <beans> element • @Profile annotation on configuration classes • @Profile annotation on individual component classes Not confidential. Tell everyone. 50
  • 52. Environment Configuration Associating specific bean definitions with specific environments • XML profile attribute on <beans> element • @Profile annotation on configuration classes • @Profile annotation on individual component classes Activating specific profiles by name • e.g. through a system property • -Dspring.profiles.active=development • or other means outside of the deployment unit • according to environment conventions Not confidential. Tell everyone. 50
  • 53. Environment Configuration Associating specific bean definitions with specific environments • XML profile attribute on <beans> element • @Profile annotation on configuration classes • @Profile annotation on individual component classes Activating specific profiles by name • e.g. through a system property • -Dspring.profiles.active=development • or other means outside of the deployment unit • according to environment conventions Not confidential. Tell everyone. 50
  • 54. Environment Configuration Associating specific bean definitions with specific environments • XML profile attribute on <beans> element • @Profile annotation on configuration classes • @Profile annotation on individual component classes Activating specific profiles by name • e.g. through a system property • -Dspring.profiles.active=development • or other means outside of the deployment unit • according to environment conventions Ideally: no need to touch deployment unit across different stages/ environments Not confidential. Tell everyone. 50
  • 55. Environment Abstraction Not confidential. Tell everyone. 51
  • 56. Environment Abstraction Grouping bean definitions for activation in specific environments • e.g. development, testing, production • possibly different deployment environments Custom resolution of placeholders • dependent on the actual environment • hierarchy of property sources Not confidential. Tell everyone. 51
  • 57. Environment Abstraction Grouping bean definitions for activation in specific environments • e.g. development, testing, production • possibly different deployment environments Custom resolution of placeholders • dependent on the actual environment • hierarchy of property sources Not confidential. Tell everyone. 51
  • 58. Environment Abstraction Grouping bean definitions for activation in specific environments • e.g. development, testing, production • possibly different deployment environments Custom resolution of placeholders • dependent on the actual environment • hierarchy of property sources Injectable environment abstraction API • org.springframework.core.env.Environment Not confidential. Tell everyone. 51
  • 59. Environment Abstraction Grouping bean definitions for activation in specific environments • e.g. development, testing, production • possibly different deployment environments Custom resolution of placeholders • dependent on the actual environment • hierarchy of property sources Injectable environment abstraction API • org.springframework.core.env.Environment Unified property resolution SPI • org.springframework.core.env.PropertyResolver Not confidential. Tell everyone. 51
  • 60. Getting Beans from Strange Places An ApplicationContextInitializer public interface ApplicationContextInitializer <C extends ConfigurableApplicationContext> { void initialize(C applicationContext); } Not confidential. Tell everyone. 52
  • 61. DEMO Demos: • FactoryBeans • SpEL • Profiles • ApplicationContextInitializers Not confidential. Tell everyone. 53
  • 62. Other Things Core Spring Supports transparent service remoting seamless JMX support, both consuming and exposing transaction management • (which we’ll look at shortly) job scheduling thread management object to XML marshalling Not confidential. Tell everyone. 54
  • 63. Spring Roo provides domain driven design and RAD for your enterprise Java applications Needs to be seen to be believed, so... Not confidential. Tell everyone. 55
  • 64. DEMO Spring Roo ALSO: come see my talk on Spring Roo applications! Not confidential. Tell everyone. 56
  • 65. The Cloud Spring works reliably on many, many clouds. Cloud Foundry is an ideal place for your Spring applications to run • they’ll be well fed and cared for • lots of nice services to play with (Redis, RabbitMQ, MySQL, PostgreSQL, MongoDB) • there are nice Spring API integrations for all of those! Not confidential. Tell everyone. 57
  • 66. DEMO Setting up a Redis-caching, PostgreSQL-using Spring app on MCF ALSO: come see my talk on building Cloud Foundry applications! Not confidential. Tell everyone. 58
  • 67. SPRING: a WALKING TOURThe Service Side 59
  • 68. Spring’s Transaction Management Hierarchies Not confidential. Tell everyone. 60
  • 69. Spring’s Transaction Support Rooted at PlatformTransactionManager • Many middleware services expose common notions about units of work: • begin • do work (N times) • commit • if error when committing, rollback • end • The devil’s in the details • Hibernate’s got its Session API • JTA has its own API (and server lock-in problems) • JPA has its EntityManager API • JDBC has the Connection and PreparedStatement APIs • JMS has its Session API Not confidential. Tell everyone. 61
  • 70. Spring’s Transaction Support PlatformTransactionManager encompasses common concerns across transactional resources package org.springframework.transaction; public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException; } Not confidential. Tell everyone. 62
  • 71. Many Implementations Not confidential. Tell everyone. 63
  • 72. Spring’s Transaction Support TransactionTemplate exposes low-level support for working with PlatformTransactionManagerfinal JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);DataSource ds = .... ;PlatformTransactionManager platformTransactionManager = new DataSourceTransactionManager( ds);TransactionTemplate transactionTemplate = new TransactionTemplate( platformTransactionManager ) ;Customer result = transactionTemplate.execute( new TransactionCallback<Customer>() { public Customer doInTransaction(TransactionStatus status) { RowMapper <Customer> rowMapper = ... ; return jdbcTemplate.queryForObject( "select * from CUSTOMERS", rowMapper) ; }}) ; Not confidential. Tell everyone. 64
  • 73. Spring’s Transaction Support Use Spring’s Declarative Transaction Management Instead @Configuration @EnableTransactionManagement public class ServiceConfiguration { @Bean public PlatformTransactionManager jpaTransactionManager (){ ... } } @Service public class CustomerService { @Transactional public Customer createCustomer( String firstName, String lastName) { // .... } } Not confidential. Tell everyone. 65
  • 74. Spring’s Cache Support Not confidential. Tell everyone. 66
  • 75. Cache Abstraction 67
  • 76. Cache Abstraction CacheManager and Cache abstraction • in org.springframework.cache • which up until 3.0 just contained EhCache support • particularly important with the rise of distributed caching • not least of it all: in cloud environments 67
  • 77. Cache Abstraction CacheManager and Cache abstraction • in org.springframework.cache • which up until 3.0 just contained EhCache support • particularly important with the rise of distributed caching • not least of it all: in cloud environments 67
  • 78. Cache Abstraction CacheManager and Cache abstraction • in org.springframework.cache • which up until 3.0 just contained EhCache support • particularly important with the rise of distributed caching • not least of it all: in cloud environments Backend adapters for EhCache, GemFire, Coherence, etc • EhCache adapter shipping with Spring core • JSR-107 a.k.a. JCache support coming in Spring 3.2 67
  • 79. Cache Abstraction CacheManager and Cache abstraction • in org.springframework.cache • which up until 3.0 just contained EhCache support • particularly important with the rise of distributed caching • not least of it all: in cloud environments Backend adapters for EhCache, GemFire, Coherence, etc • EhCache adapter shipping with Spring core • JSR-107 a.k.a. JCache support coming in Spring 3.2 67
  • 80. Cache Abstraction CacheManager and Cache abstraction • in org.springframework.cache • which up until 3.0 just contained EhCache support • particularly important with the rise of distributed caching • not least of it all: in cloud environments Backend adapters for EhCache, GemFire, Coherence, etc • EhCache adapter shipping with Spring core • JSR-107 a.k.a. JCache support coming in Spring 3.2 Specific cache setup per environment – through profiles? • potentially even adapting to a runtime-provided service 67
  • 81. Declarative Caching 68
  • 82. Declarative Caching@Cacheablepublic Owner loadOwner(int id); 68
  • 83. Declarative Caching@Cacheablepublic Owner loadOwner(int id);@Cacheable(condition="name.length < 10") 68
  • 84. Declarative Caching@Cacheablepublic Owner loadOwner(int id);@Cacheable(condition="name.length < 10")public Owner loadOwner(String name); 68
  • 85. Declarative Caching@Cacheablepublic Owner loadOwner(int id);@Cacheable(condition="name.length < 10")public Owner loadOwner(String name); 68
  • 86. Declarative Caching@Cacheablepublic Owner loadOwner(int id);@Cacheable(condition="name.length < 10")public Owner loadOwner(String name);@CacheEvict 68
  • 87. Declarative Caching@Cacheablepublic Owner loadOwner(int id);@Cacheable(condition="name.length < 10")public Owner loadOwner(String name);@CacheEvictpublic void deleteOwner(int id); 68
  • 88. JDBC Not confidential. Tell everyone. 69
  • 89. JDBC Support with Spring DataSourceTransactionManager • implements transaction support for JDBC JdbcTemplate • provides convenient one-liner template methods for common JDBC calls JDBC command objects (like SimpleJdbcInsert) Not confidential. Tell everyone. 70
  • 90. JdbcTemplate convenience // insertsRowMapper<Customer> customerRowMapper = new RowMapper<Customer>() { public Customer mapRow(ResultSet resultSet, int i) throws SQLException { long id = resultSet.getInt("id"); String firstName = resultSet.getString("first_name"); String lastName = resultSet.getString("last_name"); return new Customer(id, firstName, lastName); } };}// readsLong id = 23L;jdbcTemplate.queryForObject( “select * from customers where id = ? “, customerRowMapper, id); Not confidential. Tell everyone. 71
  • 91. JDBC Inserts with SimpleJdbcInsertMap<String, Object> args = new HashMap<String, Object>();args.put("first_name", fn);args.put("last_name", ln);SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(jdbcTemplate);simpleJdbcInsert.setTableName("customer");simpleJdbcInsert.setColumnNames(new ArrayList<String>(args.keySet()));simpleJdbcInsert.setGeneratedKeyName("id");Number id = simpleJdbcInsert.executeAndReturnKey(args); Not confidential. Tell everyone. 72
  • 92. DEMO• Looking at, and running, a JDBC-based client Not confidential. Tell everyone.
  • 93. JPA Not confidential. Tell everyone. 74
  • 94. JPA Support with Spring JpaTransactionManager • implements transaction support for JPA LocalContainerEntityManagerFactoryBean • installs support for using @EntityManager and @EntityManagerFactory to inject EntityManager(Factory) references EntityManager access is transparently thread-safe Requires no XML • no persistence.xml, or orm.xml Not confidential. Tell everyone. 75
  • 95. Configure JPA Support Easily HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter(); jpaVendorAdapter.setGenerateDdl(true); LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean(); emfb.setDataSource(dataSource()); emfb.setPackagesToScan(Customer.class.getPackage().getName()); emfb.setJpaVendorAdapter(jpaVendorAdapter); Not confidential. Tell everyone. 76
  • 96. Consuming JPA from your Services@PersistenceContextprivate EntityManager entityManager;@Transactional(readOnly = true)public Customer getCustomerById(long id) { return this.entityManager.find(Customer.class, id);} Not confidential. Tell everyone. 77
  • 97. DEMO Demos:• Looking at, and running a JPA based client Not confidential. Tell everyone.
  • 98. Hibernate Not confidential. Tell everyone. 79
  • 99. Hibernate Support with Spring Supports Hibernate 3 and 4 Requires no XML LocalSessionFactoryBuilder, LocalSessionFactoryBean Supports thread-local based Hibernate Session access transparently Not confidential. Tell everyone. 80
  • 100. Easy to Use in Code@Transactional(readOnly = true)public List<Customer> getAllCustomers() { Session session = sessionFactory.getCurrentSession(); List<Customer> customers = session.createCriteria(Customer.class).list(); return customers;} Not confidential. Tell everyone. 81
  • 101. DEMO Demos:• Looking at Spring 3.1’s refined XML-free and fluid Hibernate 4 support Not confidential. Tell everyone.
  • 102. Batch Processing Not confidential. Tell everyone. 83
  • 103. Why we’re here... Not confidential. Tell everyone. 84
  • 104. ...So, What’s the Problem? Not confidential. Tell everyone. 85
  • 105. Job and Step Job * Step * JobInstance Step Scope * JobExecution * StepExecution Not confidential. Tell everyone. 86
  • 106. Getting Started Application Developer implements ItemProcessor (optional) input output (optional) configures ItemReader ItemWriter Job * StepExecutor concerns Step RepeatOperations ExceptionHandler Not confidential. Tell everyone. 87
  • 107. Spring Batch Supports Batch API... • Jobs have Steps • Steps have Readers, and optional Processors and Writers • Readers read data • Processors process data coming into them, optionally transforming it. Optional. • Writers write data out Not confidential. Tell everyone. 88
  • 108. ItemReader public interface ItemReader<T> { T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException; }Returns null at end of dataset delegate Exception handling to framework Not confidential. Tell everyone. 89
  • 109. ItemProcessor (Optional) public interface ItemProcessor<I, O> { O process(I item) throws Exception; }Delegate Exception handling to framework Not confidential. Tell everyone. 90
  • 110. ItemWriter public interface ItemWriter<T> { void write(List<? extends T> items) throws Exception; }expects a “chunk” delegate Exception handling to framework Not confidential. Tell everyone. 91
  • 111. All Together...<job id="skipJob" incrementer="incrementer" xmlns="http://www.springframework.org/schema/batch"> <step id="step1"> <tasklet> <chunk reader="fileItemReader" processor="tradeProcessor" writer="tradeWriter" commit-interval="3" skip-limit="10"> </chunk> </tasklet> <next on="*" to="step2" /> <next on="COMPLETED WITH SKIPS" to="errorPrint1" /> <fail on="FAILED" exit-code="FAILED" /> </step></job> Not confidential. Tell everyone. 92
  • 112. DEMO Demos:• Processing File Data with Spring Batch Not confidential. Tell everyone.
  • 113. Integration with Messaging in Spring (generally) Not confidential. Tell everyone. 94
  • 114. Common Idioms in all of Spring’s Messaging Support (Amqp|Jms)Template • eliminates tedious resource acquisition, setup, management, and destruction • provides easy one-liner template methods that facilitate sending, and receiving messages • receiving messages is synchronous MessageListenerContainers • provide a clean, POJO-centric, asynchronous way to receive messages Plays nicely with the PlatformTransactionManager SPI impls MessageConverters • transparently transform message payloads into canonical data formats like JSON, XML • MLCs, *Templates both support MessageConverters for sending and receiving Lots of Options • JMS, AMQP, Redis, GemFire Not confidential. Tell everyone. 95
  • 115. Integration with JMS Not confidential. Tell everyone. 96
  • 116. Anatomy of a JMS Application Not confidential. Tell everyone. 97
  • 117. Spring’s JMS support makes JMS easy JmsTemplate reduces tedious boilerplate code to one liners JMS MessageListenerContainer SPIs make it easy to asynchronously respond to messages • POJO centric • Same idiom’s available across the entire framework Not confidential. Tell everyone. 98
  • 118. Easy to Configure@Beanpublic MessageConverter messageConverter() { MarshallingMessageConverter marshallingMessageConverter = new MarshallingMessageConverter(); marshallingMessageConverter.setMarshaller(this.oxmMarshaller()); marshallingMessageConverter.setTargetType(MessageType.TEXT); marshallingMessageConverter.setUnmarshaller(this.oxmMarshaller()); return marshallingMessageConverter;}@Beanpublic JmsTemplate jmsTemplate() throws Exception { JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory()); jmsTemplate.setMessageConverter( messageConverter()); // optional return jmsTemplate;} Not confidential. Tell everyone. 99
  • 119. Easy to Use in Code Customer customer = new Customer("Mario", "Gray"); String queue = "customers"; jmsTemplate.convertAndSend(queue, customer); Customer ogCustomer = (Customer) jmsTemplate.receiveAndConvert(queue); Not confidential. Tell everyone. 100
  • 120. DEMO Demos:• Sending and Receiving Data with Spring’s JMS support Not confidential. Tell everyone.
  • 121. Integration with AMQP Not confidential. Tell everyone. 102
  • 122. AMQP is not the ORIGINAL “Cloud Scale Messaging” ....but close enough! 103
  • 123. RabbitMQ – Messaging that Just Works Robust High-performance Easy to use AMQP LEADER
  • 124. Why AMQP? A Protocol, not an API •A defined set of messaging capabilities called the AMQ model •A network wire-level protocol, AMQP On commodity hardware •10-25 thousand messages per second is routine * •The NIC is usually the bottleneck * Non-persistent messages17
  • 125. Anatomy of an AQMP Application Not confidential. Tell everyone. 106
  • 126. AMQP Architecture café deliveries queue café NA deliveries queue café WW deliveries queue 20
  • 127. AMQP Architecture café deliveries queue café NA deliveries queue café WW deliveries queue 20
  • 128. AMQP Architecture café deliveries M1 M2 M3 queue café NA deliveries M1 M2 M3 queue café WW deliveries M1 M2 M3 queue 20
  • 129. AMQP Architecture café deliveries queue café NA deliveries queue café WW deliveries queue 20
  • 130. AMQP Architecture 19
  • 131. AMQP Architecture new.order queue 19
  • 132. AMQP Architecture new.order new.order binding queue 19
  • 133. AMQP Architecture new.order new.order new.order routing key binding queue 19
  • 134. AMQP Architecture new.order new.order new.order routing key binding queue 19
  • 135. AMQP Architecture new.order new.order new.order routing key binding queue 19
  • 136. AMQP Architecture 21
  • 137. AMQP Architecture all_drinks queue 21
  • 138. AMQP Architecture all_drinks queue cold_drinks queue 21
  • 139. AMQP Architecture all_drinks queue cold_drinks queue hot_drinks queue 21
  • 140. AMQP Architecture all_drinks queue .* drink cold_drinks queue hot_drinks queue 21
  • 141. AMQP Architecture all_drinks queue .* drink drink.cold cold_drinks queue hot_drinks queue 21
  • 142. AMQP Architecture all_drinks queue .* drink drink.cold cold_drinks queue dri nk. ho hot_drinks t queue 21
  • 143. AMQP Architecture all_drinks queue .* drink drink.cold cold_drinks queue dri nk. ho hot_drinks t queue Message Routing Keys: 1.drink.hot 2.drink.cold 3.drink.warm 21
  • 144. AMQP Architecture all_drinks 1 2 3 queue .* drink drink.cold cold_drinks 2 queue dri nk. ho hot_drinks t 1 queue Message Routing Keys: 1.drink.hot 2.drink.cold 3.drink.warm 21
  • 145. Spring AMQP Encapsulates low-level details Producer Consumer Simplifies sending and receiving of messages Amqp Listener Template Container Spring AMQP AMQP Not confidential. Tell everyone.
  • 146. Spring’s AMQP support makes AMQP easy AMQP is protocol centric • numerous clients for any number of language bindings AMQP surfaces more of the administration concerns over the protocol • easy to create queues, bindings, exchanges from client APIs Not confidential. Tell everyone. 111
  • 147. Spring’s AMQP support makes AMQP easy AmqpTemplate AMQP MessageListenerContainer SPIs make it easy to asynchronously respond to messages • POJO centric AMQP’s server side constructs (queues, bindings, etc.) can be manipulated from the client APIs Not confidential. Tell everyone. 112
  • 148. Easy to Configure @Bean public MessageConverter jsonMessageConverter() { MarshallingMessageConverter marshallingMessageConverter = new MarshallingMessageConverter(); marshallingMessageConverter.setMarshaller(this.oxmMarshaller()); marshallingMessageConverter.setUnmarshaller(this.oxmMarshaller()); return marshallingMessageConverter; } @Bean public RabbitTemplate rabbitTemplate() { RabbitTemplate rabbitTemplate = newRabbitTemplate(connectionFactory()); rabbitTemplate.setMessageConverter(jsonMessageConverter()); return rabbitTemplate; } Not confidential. Tell everyone. 113
  • 149. Easy to Configure@Beanpublic AmqpAdmin amqpAdmin() { return new RabbitAdmin(this.connectionFactory());}@Beanpublic Queue customerQueue() { Queue q = new Queue(this.customersQueueAndExchangeName); amqpAdmin().declareQueue(q); return q;}@Beanpublic DirectExchange customerExchange() { DirectExchange directExchange = new DirectExchange(“customers”); this.amqpAdmin().declareExchange(directExchange); return directExchange;}@Beanpublic Binding marketDataBinding() { return BindingBuilder.bind(customerQueue()) .to(customerExchange()) .with(this.customersQueueAndExchangeName);} Not confidential. Tell everyone. 114
  • 150. Easy to Use in CodeCustomer customer = new Customer("Mario", "Gray");amqpTemplate.convertAndSend( “exchange”, “routingkey”, customer);Customer ogCustomer = (Customer) amqpTemplate.receiveAndConvert(“queue”); Not confidential. Tell everyone. 115
  • 151. DEMO Demos:• Sending and receiving data with Spring’s AMQP support Not confidential. Tell everyone.
  • 152. Integration with Spring Integration Not confidential. Tell everyone. 117
  • 153. What is Spring Integration Generic framework for building messaging-based applications Hides nuances of external systems (be they AMQP, JMS, email, FTP, TCP, etc.): everything’s a Message Not confidential. Tell everyone. 118
  • 154. Declare channels <channel id = “stocksChannel” /> Not confidential. Tell everyone. 119
  • 155. Send Messages over JMS <channel id = “stockChannel” /> <jms:outbound-channel-adapter channel = “stockChannel” destination-name=“stocks” connection-factory = “connectionFactory” /> Not confidential. Tell everyone. 120
  • 156. Connect Components with Channelspublic class StockClientImpl { @Value(“#{stocksChannel}”) private MessageChannel channel ; @Autowired private MessagingTemplate messagingTemplate ; public void publishStockUpdate ( String stock , double price ) { Message msg = MessageBuilder .withPayload(price) .setHeader(“stock”, stock).build(); this.messagingTemplate.send( this.channel, msg ) ; }} Not confidential. Tell everyone. 121
  • 157. Being Notified of Files When They Appear<file:inbound-channel-adapter auto-create-directory="true" channel="filesReceived" directory="#{systemProperties[user.home]}/Desktop/in"> <int:poller fixed-rate="1000"/> </file:inbound-channel-adapter> <int:service-activator input-channel="filesReceived" ref="myPojo" />@ServiceActivatorpublic class MyPojo { public void myCustomFileCallback ( @Payload File fileReceived) { // do something with the file }} Not confidential. Tell everyone. 122
  • 158. DEMO• Reading file Data with Spring Integration Not confidential. Tell everyone.
  • 159. Spring Data Not confidential. Tell everyone. 124
  • 160. http://www.springsource.org/spring-data•Spring Data Key-value•Spring Data Document•Spring Data Graph•Spring Data Column•Spring Data Blob•Spring Data JPA Repository / JDBC Extensions•Spring Gemfire / Spring Hadoop ...•Grails iNcOnSeQuentiaL 125
  • 161. Spring Data Building Blocks•Low level data access APIs ✓MongoTemplate, RedisTemplate ...•Object Mapping (Java and GORM)•Cross Store Persistence Programming model•Generic Repository support•Productivity support in Roo and Grails 126
  • 162. NoSQL with Redis Not confidential. Tell everyone. 127
  • 163. NoSQL offers several data store categoriesKey-Value Column Document Graph Redis, Riak 128
  • 164. Spring Data Redis Works with Redis • super fast • “data structure server” (maps, lists, sets, queue, etc.) RedisTemplate reduces tedious boilerplate code to one liners CacheManager implementation • works with Spring 3.1’s CacheManager implementation RedisMessageListenerContainer • provides same queue / publish-subscribe features as with JMS and AMQP Not confidential. Tell everyone. 129
  • 165. Configuring Redis support@Bean public RedisConnectionFactory redisConnectionFactory() { return new JedisConnectionFactory(); } @Bean public RedisTemplate<String, Object> redisTemplate() throws Exception { RedisTemplate<String, Object> ro = new RedisTemplate<String, Object>(); ro.setConnectionFactory(redisConnectionFactory()); return ro; } NOT CONFIDENTIAL -- TELL EVERYONE 130
  • 166. Handling Persistence Duties with Redis...@Inject RedisTemplate redisTemplate;@Overridepublic Customer getCustomerById(long id) { String ln = (String)redisTemplate.opsForValue().get(lastNameKey(id)) ; String fn = (String)redisTemplate.opsForValue().get(firstNameKey(id)); return new Customer(id, fn, ln);}private void setCustomerValues(long lid, String fn, String ln) { this.redisTemplate.opsForValue().set(lastNameKey(lid), ln); this.redisTemplate.opsForValue().set(firstNameKey(lid), fn); }@Overridepublic Customer updateCustomer(long id, String fn, String ln) { setCustomerValues(id, fn, ln); return getCustomerById(id);} NOT CONFIDENTIAL -- TELL EVERYONE 131
  • 167. DEMO• Reimplementing the CustomerService interface in terms of Redis• introduce Spring 3.1 caching support• Introduce RedisCacheManager implementation• Not confidential. Tell everyone.
  • 168. NoSQL with MongoDB Not confidential. Tell everyone. 133
  • 169. NoSQL offers several data store categoriesKey-Value Column Document Graph MongoDB 134
  • 170. Spring Data MongoDB works with MongoDB provides obvious API integrations: • MongoTemplate • Mongo-backed MessageStore (Spring Integration) Advanced API integrations, too: • cross-store persistence • MongoRepository (built on Spring Data JPA) Not confidential. Tell everyone. 135
  • 171. Simple Domain Class 136
  • 172. Mongo TemplateDirect Usage of the Mongo Template: 137
  • 173. Mongo TemplateDirect Usage of the Mongo Template: Insert into “Person” Collection 137
  • 174. Mongo TemplateDirect Usage of the Mongo Template: findOne using query: { "name" : "Joe"} in db.collection: database.Person 137
  • 175. Mongo TemplateDirect Usage of the Mongo Template: Dropped collection [database.person] 137
  • 176. Generic RepositoryInterface for generic CRUD operations on a repository for a specific type 138
  • 177. Paging and Sorting RepositoryPaging and Sorting Repository: Extends “CrudRepository” 139
  • 178. Paging and Sorting RepositoryPaging and Sorting Repository: Extends “CrudRepository” Usage: 139
  • 179. Custom RepositoryCustom Repository: 140
  • 180. Custom RepositoryCustom Repository:Keywords :Keyword Sample Logical resultGreaterThan findByAgeGreaterThan(int age) {"age" : {"$gt" : age}}LessThan findByAgeLessThan(int age) {"age" : {"$lt" : age}}Between findByAgeBetween(int from, int to) {"age" : {"$gt" : from, "$lt" : to}}NotNull findByFirstnameNotNull() {”firstname" : {"$ne" : null}}Null findByFirstnameNull() {”firstname" : null}Like findByFirstnameLike(String name) "firstname" : firstname} (regex) 140
  • 181. JPA and MongoDB can be used in cross-store persistence JPA “Customer” with a “SurveyInfo” Document 141
  • 182. Using a Cross-Store Saving a Customer with a SurveryInfo 142
  • 183. Using a Cross-Store Saving a Customer with a SurveryInfo Create Customer 142
  • 184. Using a Cross-Store Saving a Customer with a SurveryInfo Create SurveyInfo 142
  • 185. Using a Cross-Store Saving a Customer with a SurveryInfo Assign Survey to Customer 142
  • 186. Using a Cross-Store Saving a Customer with a SurveryInfo Save 142
  • 187. Using a Cross-Store Saving a Customer with a SurveryInfo Save Mongo Document: 142
  • 188. DEMO• Looking at Mongo Repository• Look at a Cross-Store Persistence Example Not confidential. Tell everyone.
  • 189. SPRING: a WALKING TOURThe Client Side 144
  • 190. Agenda Web Applications • Spring MVC • JSF • Others REST • the final frontier: TV, tablets, operating systems Mobile Clients • Android • iPhone RIA / SOFEA • Flex • GWT, Vaadin 145
  • 191. Web Applications with Spring 146
  • 192. The Spring ApplicationContext Spring Beans are Managed by An ApplicationContext • whether you’re in an application server, a web server, in regular Java SE application, in the cloud, Spring is initialized through an ApplicationContext • In a Java SE application: ApplicationContext ctx = new GenericAnnotationApplicationContext( “com.foo.bar.my.package”); • In a web application, you will configure an application context in your web.xml <servlet> <servlet-name>Spring Dispatcher Servlet</servlet-name> <servlet- class>org.springframework.web.servlet.DispatcherServlet</servlet- class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/myAppContext*.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> 147
  • 193. The Spring ApplicationContext Spring Beans are Managed by An ApplicationContext • In Spring 3.1, you can also use Java configuration, negating the need for web.xml public class SampleWebApplicationInitializer implements WebApplicationInitializer { public void onStartup(ServletContext sc) throws ServletException { AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext(); ac.setServletContext(sc); ac.scan( “a.package.full.of.services”, “a.package.full.of.controllers” ); sc.addServlet("spring", new DispatcherServlet(webContext)); } } 148
  • 194. Thin, Thick, Web, Mobile and Rich Clients: Web Core Spring Dispatcher Servlet • Objects don’t have to be web-specific. • Spring web supports lower-level web machinery: ‘ • HttpRequestHandler (supports remoting: Caucho, Resin, JAX RPC) • DelegatingFilterProxy. • HandlerInterceptor wraps requests to HttpRequestHandlers • ServletWrappingController lets you force requests to a servlet through the Spring Handler chain • OncePerRequestFilter ensures that an action only occurs once, no matter how many filters are applied. Provides a nice way to avoid duplicate filters • Spring provides access to the Spring application context using WebApplicationContextUtils, which has a static method to look up the context, even in environments where Spring isn’t managing the web components
  • 195. Thin, Thick, Web, Mobile and Rich Clients: Web Core Spring provides the easiest way to integrate with your web framework of choice • Spring Faces for JSF 1 and 2 • Struts support for Struts 1 • Tapestry, Struts 2, Stripes, GWT, Wicket, Vaadin, Play framework, etc.
  • 196. Thin, Thick, Web, Mobile and Rich Clients: Spring MVC 151
  • 197. The Client Side: Spring MVCSpring MVC configuration - config @Configuration @EnableWebMvc @Import(JdbcConfiguration.class) public class WebConfig extends WebMvcConfigurerAdapter { @Bean public UrlBasedViewResolver resolver() { UrlBasedViewResolver url = new UrlBasedViewResolver(); url.setPrefix("views/"); url.setViewClass(JstlView.class); url.setSuffix(".jsp"); return url; } @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("welcome"); } @Override public void configureDefaultServletHandling( DefaultServletHandlerConfigurer configurer) { configurer.enable(); } } 152
  • 198. The Client Side: Spring MVC A Controller - config @Controller public class CustomerController { private Log log = LogFactory.getLog(getClass()); @Autowired private CustomerService customerService; @ModelAttribute public Customer customer() { return new Customer(); } @RequestMapping(value = "/display", method = RequestMethod.GET) public Map<String, Object> customer(@RequestParam("id") Long id) { Customer customerById = this.customerService.getCustomerById(id); Map<String, Object> out = new HashMap<String, Object>(); out.put("customer", customerById); return out; } @RequestMapping(value = "/add", method = RequestMethod.POST) public String processAddition(@ModelAttribute Customer c, Model modelAndView) { Customer customer = customerService.createCustomer( c.getFirstName(), c.getLastName()); modelAndView.addAttribute("id", customer.getId()); return "redirect:/display"; } } 153
  • 199. DEMO Demos • Spring MVC and associated configuration Not confidential. Tell everyone.
  • 200. REST 155
  • 201. Thin, Thick, Web, Mobile and Rich Clients: REST Spring MVC is basis for REST support • Spring’s server side REST support is based on the standard controller model RestTemplate • provides dead simple, idiomatic RESTful services consumption • can use Spring OXM, too. • Spring Integration and Spring Social both build on the RestTemplate where possible. JavaScript and HTML5 can consume JSON-data payloads REST is the ultimate connectivity mechanism: everything can speak HTTP.
  • 202. Thin, Thick, Web, Mobile and Rich Clients: REST Origin • The term Representational State Transfer was introduced and defined in 2000 by Roy Fielding in his doctoral dissertation. His paper suggests these four design principles: • Use HTTP methods explicitly. • POST, GET, PUT, DELETE • CRUD operations can be mapped to these existing methods • Be stateless. • State dependencies limit or restrict scalability • Expose directory structure-like URIs. • URI’s should be easily understood • Transfer XML, JavaScript Object Notation (JSON), or both. • Use XML or JSON to represent data objects or attributes CONFIDENTIAL 157
  • 203. Thin, Thick, Web, Mobile and Rich Clients: RestTemplate Google search exampleRestTemplate restTemplate = new RestTemplate();String url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q={query}";String result = restTemplate.getForObject(url, String.class, "SpringSource"); Multiple parametersRestTemplate restTemplate = new RestTemplate();String url = "http://example.com/hotels/{hotel}/bookings/{booking}";String result = restTemplate.getForObject(url, String.class, "42", “21”); CONFIDENTIAL 158
  • 204. Thin, Thick, Web, Mobile and Rich Clients: RestTemplate RestTemplate class is the heart the client-side story • Entry points for the six main HTTP methods • DELETE - delete(...) • GET - getForObject(...) • HEAD - headForHeaders(...) • OPTIONS - optionsForAllow(...) • POST - postForLocation(...) • PUT - put(...) • any HTTP operation - exchange(...) and execute(...) CONFIDENTIAL 159
  • 205. Thin, Thick, Web, Mobile and Rich Clients: RestTemplate Http Client • The HttpComponents HttpClient is a native HTTP client Message Converters • MappingJacksonHttpMessageConverter - object to JSON marshaling supported via the Jackson JSON Processor • MarshallingXmlMessageConverter - converts objects to XML using Spring OXM • SyndFeedHttpMessageConverter - RSS and Atom feeds supported via the Android ROME Feed Reader CONFIDENTIAL 160
  • 206. Thin, Thick, Web, Mobile and Rich Clients: REST with Spring MVCRestCustomerController - server@Controller @RequestMapping(headers = "Accept=application/json, application/xml")public class RestCustomerController { @Autowired private CustomerService cs; @RequestMapping(value = "/customer/{cid}", method = RequestMethod.POST) @ResponseBody public Customer updateCustomer(@RequestBody Customer c) { return cs.updateCustomer( c.getId(), c.getFirstName(), c.getLastName()); } WebConfig - server @EnableWebMvc @Import(Config.class) @Configuration public class WebConfig extends WebMvcConfigurerAdapter {} client Customer customer1 = restTemplate.getForEntity( url + "customer/{customerId}", Customer.class, c.getId()).getBody(); log.info("fetched customer " + customer1.toString()); 161
  • 207. DEMO Demos:• Spring REST service• Spring REST client Not confidential. Tell everyone.
  • 208. Mobile (pt 1.) 163
  • 209. Thin, Thick, Web, Mobile and Rich Clients: Mobile Best strategy? Develop Native • Fallback to client-optimized web applications Spring MVC 3.1 mobile client-specific content negotiation and rendering • for other devices • (there are other devices besides Android??) 164
  • 210. Thin, Thick, Web, Mobile and Rich Clients: Mobile WebConfig - server! @Bean public ViewResolver viewResolver() { UrlBasedViewResolver viewResolver = new UrlBasedViewResolver(); viewResolver.setViewClass(TilesView.class); return viewResolver; } @Bean public TilesConfigurer tilesConfigurer() { TilesConfigurer configurer = new TilesConfigurer(); configurer.setDefinitions(new String[]{ "/WEB-INF/layouts/tiles.xml", "/WEB-INF/views/**/tiles.xml" }); configurer.setCheckRefresh(true); return configurer; } @Override public void configureInterceptors(InterceptorConfigurer configurer) { configurer.addInterceptor(new DeviceResolverHandlerInterceptor()); } 165
  • 211. DEMO Demos:• Mobile clients using client specific rendering Not confidential. Tell everyone.
  • 212. Mobile (pt 2.) 167
  • 213. Thin, Thick, Web, Mobile and Rich Clients: Mobile  Spring REST is ideal for mobile devices  Spring MVC 3.1 mobile client-specific content negotiation and rendering • for other devices  Spring Android • RestTemplate 168
  • 214. OK, so..... 169
  • 215. Thin, Thick, Web, Mobile and Rich Clients: Mobile CustomerServiceClient - client! private <T> T extractResponse( ResponseEntity<T> response) {! ! if (response != null && response().value() == 200) {! ! ! return response.getBody();! ! }! ! throw new RuntimeException("couldnt extract response.");! }! @Override! public Customer updateCustomer(long id, String fn, String ln) {! ! String urlForPath = urlForPath("customer/{customerId}");!!! ! return extractResponse(this.restTemplate.postForEntity( urlForPath, new Customer(id, fn, ln), Customer.class, id));! } 170
  • 216. Thin, Thick, Web, Mobile and Rich Clients: Mobile Demos:• consuming the Spring REST service from Android
  • 217. Rich Internet Applications 172
  • 218. Thin, Thick, Web, Mobile and Rich Clients: Flex  Spring Flex • Dead-simple to expose Spring beans as Flex services • Developed with support from Adobe • But it still has strengths: • form driven apps • video, 2D and 3D graphics, sound • Adobe AIR • blazing fast communication • server side push • Spring ActionScript is a cool framework “sponsored” by SpringSource
  • 219. Thin, Thick, Web, Mobile and Rich Clients: Flex crm-flex-servlet.xml - server<?xml version="1.0" encoding="UTF-8"?><beans ...> <context:component-scan base-package="org.springsource.examples.sawt.web.flex"/> <mvc:default-servlet-handler/> <flex:message-broker mapping-order="1"> <flex:mapping pattern="/messagebroker/*"/> <flex:message-service default-channels="my-streaming-amf,my-longpolling-amf,my-polling-amf"/> </flex:message-broker> <flex:remoting-destination ref="jdbcCustomerService" destination-id="customerService"/></beans> CustomerForm.mxml - client<fx:Declarations><s:RemoteObject id="cs" destination="customerService"endpoint="{serviceUrl}"> <s:method name="createCustomer" result="create_resultHandler(event)"/> <s:method name="updateCustomer" result="update_resultHandler(event)"/> </s:RemoteObject> </fx:Declarations><fx:Script><![CDATA[ cs.updateCustomer( c.id, c.firstName, c.lastName); ]]></fx:Script> 174
  • 220. Thin, Thick, Web, Mobile and Rich Clients: RIA with Flex Demos:• exposing Spring services through BlazeDS• consuming it from a Flex client
  • 221. Thin, Thick, Web, Mobile and Rich Clients: GWT  Google Web Toolkit • Lots of popular options • We’ll look at building a simple example by simple delegating as appropriate • Server-side: standard DispatcherServlet
  • 222. Thin, Thick, Web, Mobile and Rich Clients: GWT GwtCustomerService - clientimport com.google.gwt.user.client.rpc.*;@RemoteServiceRelativePath("crm")public interface GwtCustomerService extends RemoteService { void updateCustomer(long cid, String f, String l); CustomerDto getCustomerById(long customerId); CustomerDto createCustomer(String f, String ln);}GwtCustomerServiceImpl - server private <T> T beanOfType(Class t) { ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext( getServletContext()); return (T) ac.getBean(t); } public void updateCustomer(long cid, String f, String l) { try { CustomerService customerService = beanOfType(CustomerService.class); customerService.updateCustomer(cid, f, l); } catch (Exception ex) { throw new RuntimeException(ex); } } 177
  • 223. DEMO Demos:• building a simple GWT client that consumes services in Spring Not confidential. Tell everyone.
  • 224. Another Strategy....  HTML5 all the way! • HTML5 on the desktop browser interface • HTML5 + PhoneGap on the client • RESTful services on the server side to connect it all I NEED AN HTM here!!!!
  • 225. DEMO HTML5Expense• github.com/SpringSource/html5expenses Not confidential. Tell everyone.
  • 226. Social Communication NOT CONFIDENTIAL -- TELL EVERYONE 181
  • 227. Spring Social Extension to Spring Framework to enable connectivity with Software-as-a-Service providers Features... • An extensible connection framework • A connect controller • Java API bindings • A sign-in controller http://www.springsource.org/spring-social 182
  • 228. Spring Social Projects Spring Social Core Spring Social Facebook Spring Social Twitter Spring Social LinkedIn Spring Social TripIt Spring Social GitHub Spring Social Gowalla Spring Social Samples • Includes Showcase, Quickstart, Movies, Canvas, Twitter4J, Popup 183
  • 229. Key Steps to Socializing an Application Configure Spring Social beans • Connection Factory Locator and Connection Factories • Connection Repository • Connect Controller • API Bindings Create connection status views Inject/use API bindings 184
  • 230. Configuration: ConnectionFactoryLocator@Bean@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)public ConnectionFactoryLocator connectionFactoryLocator() { ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry(); registry.addConnectionFactory( new TwitterConnectionFactory( environment.getProperty("twitter.consumerKey"), environment.getProperty("twitter.consumerSecret"))); registry.addConnectionFactory( new FacebookConnectionFactory( environment.getProperty("facebook.clientId"), environment.getProperty("facebook.clientSecret"))); return registry;} 185
  • 231. Configuration: ConnectionFactoryLocator@Bean@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)public ConnectionFactoryLocator connectionFactoryLocator() { ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry(); registry.addConnectionFactory( new TwitterConnectionFactory( environment.getProperty("twitter.consumerKey"), environment.getProperty("twitter.consumerSecret"))); registry.addConnectionFactory( new FacebookConnectionFactory( environment.getProperty("facebook.clientId"), environment.getProperty("facebook.clientSecret"))); return registry;} 185
  • 232. Configuration: ConnectionFactoryLocator@Bean@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)public ConnectionFactoryLocator connectionFactoryLocator() { ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry(); registry.addConnectionFactory( new TwitterConnectionFactory( environment.getProperty("twitter.consumerKey"), environment.getProperty("twitter.consumerSecret"))); registry.addConnectionFactory( new FacebookConnectionFactory( environment.getProperty("facebook.clientId"), environment.getProperty("facebook.clientSecret"))); return registry;} 185
  • 233. Configuration: ConnectionFactoryLocator@Bean@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)public ConnectionFactoryLocator connectionFactoryLocator() { ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry(); registry.addConnectionFactory( new TwitterConnectionFactory( environment.getProperty("twitter.consumerKey"), environment.getProperty("twitter.consumerSecret"))); registry.addConnectionFactory( new FacebookConnectionFactory( environment.getProperty("facebook.clientId"), environment.getProperty("facebook.clientSecret"))); return registry;} 185
  • 234. Configuration: Connection Repository@Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public ConnectionRepository connectionRepository() { Authentication authentication = SecurityContextHolder.getContext(). getAuthentication(); if (authentication == null) { throw new IllegalStateException( "Unable to get a ConnectionRepository: no user signed in"); } return usersConnectionRepository().createConnectionRepository( authentication.getName());} 186
  • 235. Configuration: Connection Repository@Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public ConnectionRepository connectionRepository() { Authentication authentication = SecurityContextHolder.getContext(). getAuthentication(); if (authentication == null) { throw new IllegalStateException( "Unable to get a ConnectionRepository: no user signed in"); } return usersConnectionRepository().createConnectionRepository( authentication.getName());}@Bean@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)public UsersConnectionRepository usersConnectionRepository() { return new JdbcUsersConnectionRepository( dataSource, connectionFactoryLocator(), Encryptors.noOpText());} 186
  • 236. Configuration: ConnectController @Bean public ConnectController connectController() { return new ConnectController(connectionFactoryLocator(), connectionRepository()); } 187
  • 237. Configuration: ConnectController @Bean public ConnectController connectController() { return new ConnectController(connectionFactoryLocator(), connectionRepository()); } 187
  • 238. Configuration: ConnectController @Bean public ConnectController connectController() { return new ConnectController(connectionFactoryLocator(), connectionRepository()); } 187
  • 239. Configuration: API Bindings@Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Facebook facebook() { Connection<Facebook> facebook = connectionRepository().findPrimaryConnection(Facebook.class); return facebook != null ? facebook.getApi() : new FacebookTemplate();} @Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Twitter twitter() { Connection<Twitter> twitter = connectionRepository().findPrimaryConnection(Twitter.class); return twitter != null ? twitter.getApi() : new TwitterTemplate();} 188
  • 240. Configuration: API Bindings@Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Facebook facebook() { Connection<Facebook> facebook = connectionRepository().findPrimaryConnection(Facebook.class); return facebook != null ? facebook.getApi() : new FacebookTemplate();} @Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Twitter twitter() { Connection<Twitter> twitter = connectionRepository().findPrimaryConnection(Twitter.class); return twitter != null ? twitter.getApi() : new TwitterTemplate();} 188
  • 241. Configuration: API Bindings@Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Facebook facebook() { Connection<Facebook> facebook = connectionRepository().findPrimaryConnection(Facebook.class); return facebook != null ? facebook.getApi() : new FacebookTemplate();} @Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Twitter twitter() { Connection<Twitter> twitter = connectionRepository().findPrimaryConnection(Twitter.class); return twitter != null ? twitter.getApi() : new TwitterTemplate();} 188
  • 242. Configuration: API Bindings@Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Facebook facebook() { Connection<Facebook> facebook = connectionRepository().findPrimaryConnection(Facebook.class); return facebook != null ? facebook.getApi() : new FacebookTemplate();} @Bean@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES) public Twitter twitter() { Connection<Twitter> twitter = connectionRepository().findPrimaryConnection(Twitter.class); return twitter != null ? twitter.getApi() : new TwitterTemplate();} 188
  • 243. Injecting and Using the API Bindings @Controller public class TwitterTimelineController { private final Twitter twitter; @Inject public TwitterTimelineController(Twitter twitter) { this.twitter = twitter; } @RequestMapping(value="/twitter/tweet", method=RequestMethod.POST) public String postTweet(String message) { twitter.timelineOperations().updateStatus(message); return "redirect:/twitter"; } } 189
  • 244. Injecting and Using the API Bindings @Controller public class TwitterTimelineController { private final Twitter twitter; @Inject public TwitterTimelineController(Twitter twitter) { this.twitter = twitter; } @RequestMapping(value="/twitter/tweet", method=RequestMethod.POST) public String postTweet(String message) { twitter.timelineOperations().updateStatus(message); return "redirect:/twitter"; } } 189
  • 245. Injecting and Using the API Bindings @Controller public class TwitterTimelineController { private final Twitter twitter; @Inject public TwitterTimelineController(Twitter twitter) { this.twitter = twitter; } @RequestMapping(value="/twitter/tweet", method=RequestMethod.POST) public String postTweet(String message) { twitter.timelineOperations().updateStatus(message); return "redirect:/twitter"; } } 189
  • 246. ConnectController Endpoints GET /connect • Displays connection status for all providers GET /connect/{provider} • Displays connection status for a given provider POST /connect/{provider} • Initiates the authorization flow, redirecting to the provider GET /connect/{provider}?oauth_token={token} • Handles an OAuth 1 callback GET /connect/{provider}?code={authorization code} • Handles an OAuth 2 callback DELETE /connect/{provider} • Removes all connections for a user to the given provider DELETE /connect/{provider}/{provider user ID} • Removes a specific connection for the user to the given provider 190
  • 247. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) 191
  • 248. ConnectController Flow Your Application GET /connect/{provider ID} ConnectController Service Provider (Twitter, Facebook, etc) Display connection status page 191
  • 249. ConnectController Flow Your Application POST /connect/{provider ID} ConnectController Service Provider (Twitter, Facebook, etc) Initiate connection flow 191
  • 250. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) Fetch request token (OAuth 1.0/1.0a only) 191
  • 251. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) Redirect browser to provider’s authorization page 191
  • 252. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) Redirect browser to provider’s authorization page 191
  • 253. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) Redirect browser to provider’s authorization page 191
  • 254. ConnectController Flow Your Application GET /connect/{provider ID}?oauth_token={token} GET /connect/{provider ID}?code={code} ConnectController Service Provider (Twitter, Facebook, etc) Provider redirects to callback URL 191
  • 255. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) Exchange request token and/or code for access token 191
  • 256. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) ConnectController stores connection details in connection repository 191
  • 257. ConnectController Flow Your Application ConnectController Service Provider (Twitter, Facebook, etc) Application can make API calls via API binding 191
  • 258. Connection Status Page View<form action="<c:url value="/connect/twitter" />" method="POST"> <div class="formInfo"> <p> You havent created any connections with Twitter yet. Click the button to connect with your Twitter account. </p> </div> <p> <button type="submit"> <img src="<c:url value="/resources/social/twitter/connect-with-twitter.png" />"/> </button> </p></form> 192
  • 259. Provider Sign In A convenience for users Enables authentication to an app using their connection as credentials Implemented with ProviderSignInController Works consistently with any provider 193
  • 260. Configuration: ProviderSignInController Performs a similar flow as ConnectController Compares connections (by user ID) If there’s a match, the user is signed into the application Otherwise, the user is sent to signup page • Connection is be established after signup@Beanpublic ProviderSignInController providerSignInController( RequestCache requestCache) { return new ProviderSignInController(connectionFactoryLocator(), usersConnectionRepository(), new SimpleSignInAdapter(requestCache));} 194
  • 261. Configuration: ProviderSignInController Performs a similar flow as ConnectController Compares connections (by user ID) If there’s a match, the user is signed into the application Otherwise, the user is sent to signup page • Connection is be established after signup@Beanpublic ProviderSignInController providerSignInController( RequestCache requestCache) { return new ProviderSignInController(connectionFactoryLocator(), usersConnectionRepository(), new SimpleSignInAdapter(requestCache));} 194
  • 262. Configuration: ProviderSignInController Performs a similar flow as ConnectController Compares connections (by user ID) If there’s a match, the user is signed into the application Otherwise, the user is sent to signup page • Connection is be established after signup@Beanpublic ProviderSignInController providerSignInController( RequestCache requestCache) { return new ProviderSignInController(connectionFactoryLocator(), usersConnectionRepository(), new SimpleSignInAdapter(requestCache));} 194
  • 263. Configuration: ProviderSignInController Performs a similar flow as ConnectController Compares connections (by user ID) If there’s a match, the user is signed into the application Otherwise, the user is sent to signup page • Connection is be established after signup@Beanpublic ProviderSignInController providerSignInController( RequestCache requestCache) { return new ProviderSignInController(connectionFactoryLocator(), usersConnectionRepository(), new SimpleSignInAdapter(requestCache));} 194
  • 264. ProviderSignInController Endpoints POST /signin/{provider} • Initiates the authorization flow, redirecting to the provider GET /signin/{provider}?oauth_token={token} • Handles an OAuth 1 callback GET /signin/{provider}?code={authorization code} • Handles an OAuth 2 callback GET /signin • Handles a callback when no oauth token or code is sent • Likely indicates that the user declined authorization 195
  • 265. Social Security OAuth NOT CONFIDENTIAL -- TELL EVERYONE 196
  • 266. Spring Security OAuth Extension to Spring Security • originally a community contribution (now officially part of the project) Features... • endpoint management for OAuth service types • (along with corresponding client management) • token management (persistence, authentication) • integrations for the web, as well as through standard Spring Security springsource.org/spring-security/oauth 197
  • 267. Setup Spring Security with Spring MVC...<http access-denied-page="/login.jsp" xmlns="http://www.springframework.org/schema/security"> <form-login authentication-failure-url="/login.jsp" default-target-url="/index.jsp" login-page="/login.jsp" login-processing-url="/login.do" /> <logout logout-success-url="/index.jsp" logout-url="/logout.do" /> <anonymous /> <intercept-url pattern="/sparklr/**" access="ROLE_USER" /> <custom-filter ref="oauth2ClientFilter" after="EXCEPTION_TRANSLATION_FILTER" /></http> 198
  • 268. Then Tell Spring Security About Our OAuth Endpoints<authentication-manager xmlns="http://www.springframework.org/schema/security"> <authentication-provider> <user-service> <user name="marissa" password="wombat" authorities="ROLE_USER" /> <user name="sam" password="kangaroo" authorities="ROLE_USER" /> </user-service> </authentication-provider></authentication-manager><oauth:client id="oauth2ClientFilter" redirect-on-error="${redirectOnError:false}" /><oauth:resource id="sparklr" type="authorization_code" client-id="tonr" client-secret="secret" access-token-uri="${accessTokenUri}" user-authorization-uri="${userAuthorizationUri}" scope="read" /> 199
  • 269. Then get an Instance of a RestTemplate for the client...<bean class="org.springframework.security.oauth2.client.OAuth2RestTemplate"> <constructor-arg ref = “sparklr”/></bean> 200
  • 270. springsource.org Questions? Say hi!@starbuxman || josh.long@springsource.com