intermediate spring matt wheeler. notes this is a training not a presentation please ask questions...

33
Intermediate Spring Matt Wheeler

Upload: alexandra-devere

Post on 15-Dec-2015

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Intermediate SpringMatt Wheeler

Page 2: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Notes

• This is a training NOT a presentation• Please ask questions• Prerequisites

– Introduction to Java Stack– Basic Java and XML skills– Introduction to Spring– Introduction to Spring Part 2– Installed LDSTech IDE (or other equivalent)

Page 3: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Review

• Bean lifecycle• XML Schema-based Configuration (namespace

handlers)• Lifecycle hooks

• Bean Initialization (JSR 250, @PostConstruct, …)• Bean post processors

• Component scanning• Spring Component Annotations• DI Annotations (JSR 330, @Inject, @Named)

Page 4: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Overview

• Advanced Injection• Providers• Spring EL• Additional Injection Annotations

• Application Context web integration• Testing framework

Page 5: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Providers

• Providers allow us to defer instantiation of a resource until it is needed

• Providers facilitate (from the JavaDoc):– Retrieving multiple instances– Lazy or optimal retrieval of an instance– Breaking circular dependencies– Abstracting scope so you can look up an instance in a

smaller scope from an instance in a containing scope

Page 6: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Previous Training Lab

• We used the @Named annotation to select the prototypeRabbit to inject into the farm as the prize rabbit• The result was something like the following

• Does anyone see any problem with this?

@Componentpublic class Farm { @Inject @Named("prototypeRabbit") private Rabbit prizeRabbit;…}

Page 7: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Provider Demo

DEMO

Page 8: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Spring EL (SpEL)

• Allows access to Spring beans and properties• Supports querying and manipulating object graph

at runtime• Similar syntax to Unified EL (but more extensive)

– Method invocation, string templating• Namespace handlers use it to inject references

into attributes• For more specifics, please see the Spring docs:

– http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html

Page 9: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Spring EL Examples

• We recommend only using this when necessary– For example

• When extracting a property from a map

• Or injecting a reference into a namespace handler<property name="someProperty" value="#{systemProperties['someValue']}" />

<jee:jndi-lookup id="databasePassword" jndi-name="dbPassword" /><jee:jndi-lookup id="databaseUsername" jndi-name="dbUsername"/>

<data-source driver-class="org.h2.Driver" url="jdbc:h2:mem:stack-starter;MODE=Oracle" user="#{databaseUsername}" password="#{databasePassword}" override="true" db-env="EMBEDDED"/>

Page 10: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Additional Injection Annotations

• Many additional injection annotations

• Please refer to the Spring documentation here:– http://static.springsource.org/spring/docs/3.0.x/

spring-framework-reference/html/beans.html#beans-annotation-config

Annotation Example Description

@Value @Value("#{someBean.someProperty}") private String something

Spring EL can be used in correlation with @Value to inject a property

@Resource @Resourceprivate SomeBean someBean;

Injects by name instead of type. Can inject Collections unlike @Named. If name not explicitly specified it uses the name of the property being annotated. Does not work with Provider.

@Autowired @Autowiredprivate SomeBean someBean;

Spring proprietary annotation almost equivalent to JSR 330 @Inject but with a required attribute.

Page 11: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Lab 1: Providers

https://tech.lds.org/wiki/Intermediate_Spring#Lab_1_Advanced_Injection

Page 12: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Web Context Listener

• Loading application contexts in a web environment

Page 13: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Traditionally

• Previously we have loaded application contexts with something like:

• In a web environment however– You will want the context to automatically be loaded

on startup– And be shared across the entire application

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");SomeBean someBean = context.getBean(SomeBean.class);

Page 14: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Servlet Listeners

• The Java Servlet spec provides a listener (startup hook)– Listeners are triggered to run on startup

• Spring utilizes this functionality and has created a listener that will load the application context when the application starts up

Page 15: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Context Loader Listener

• Here is the web.xml configuration:

• Utilizes the following context parameter:

<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>

<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:META-INF/spring/applicationContext.xml,classpath:*beans.xml</param-value> <param-value>classpath:anotherContext.xml</param-value></context-param>

Page 16: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Application Contexts and Servlets

• Servlets not instantiated by Spring– Instantiated by the servlet container – Spring unable to inject dependencies

• However Spring provides a way to access the application context

Page 17: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Application Context and Servlet

• For the given servlet configuration (web.xml)

• Application Context accessed as follows:

<servlet> <servlet-name>servlet</servlet-name> <servlet-class>org.lds.training.TrainingServlet</servlet-class></servlet><servlet-mapping> <servlet-name>servlet</servlet-name> <url-pattern>/servlet</url-pattern></servlet-mapping>

public class TrainingServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //Context loader listener stores context in the servlet context - which is why it is required ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); SomeBean someBean = (SomeBean) applicationContext.getBean(SomeBean.class); someBean.printSomething(); }}

Page 18: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

A Better Way

• Spring provides a servlet that delegates to a bean that is Spring managed– Called an HttpRequestHandler– Allows annotations and injection– Create a Spring bean that matches the name of the

servlet name• This provides the mapping between the two

Page 19: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Utilizing a Spring Request Handler

• The configuration:<!– web.xml --><servlet> <servlet-name>trainingHandler</servlet-name> <servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class></servlet><servlet-mapping> <servlet-name>trainingHandler</servlet-name> <url-pattern>/trainingHandler</url-pattern></servlet-mapping>

@Component("trainingHandler")public class TrainingRequestHandler implements HttpRequestHandler { @Inject private SomeBean someBean;

public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { someBean.printSomething(); }}

Page 20: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Spring MVC and Application Contexts

• Spring MVC provides and even better way to integrate with the web container– Look forward to further discussion of this in a future

training

Page 21: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Lab 2: Web Context Listener

https://tech.lds.org/wiki/Intermediate_Spring#Lab_2_Web_Context_Liste

ner

Page 22: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Spring Testing

• Spring promotes testing in two prominent ways– Making the code more testable– Proving a testing framework

Page 23: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Testable Code

• Dependency injection decouples code from the container– POJOs are normally easier to test

• Dependencies are clearly defined– Allows you to swap implementations

Page 24: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Testing Help

• Additionally we have an application context that can manage dependencies

• Reloading the context for each test could be time consuming and unnecessary

• Spring provides support for loading the context once per JVM (unless you explicitly tell it to reload)

Page 25: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Testing Framework

• Many good testing frameworks available– JUnit– TestNG

• Spring provides a context loader for tests• Currently Spring supports JUnit 3, JUnit 4, and

TestNG – We will be using TestNG

Page 26: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Spring Test Framework

• @ContextConfiguration– Allows you to specify application contexts to load– Important: Loaded in the order specified

• Later bean definitions of the same name will override earlier ones

• Allows us to utilize everything in the project context– But selectively override bean definitions in the test contexts

• AbstractTestNGSpringContextTests

@ContextConfiguration(locations={"classpath*:*beans.xml","classpath*:*beans-test.xml"})public class FarmIT extends AbstractTestNGSpringContextTests {//…}

Page 27: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

For example

• The application bean definition file

• The test bean definition file

<jee:jndi-lookup id="securityConnectionUrl" jndi-name="ldap/URL"/><jee:jndi-lookup id="securityConnectionDN" jndi-name="ldap/DN"/><jee:jndi-lookup id="securityConnectionPassword" jndi-name="ldap/Password"/>

<bean id="securityConnectionUrl" class="java.lang.String"> <constructor-arg value="ldaps://gdirstage/" /></bean><bean id="securityConnectionDN" class="java.lang.String"> <constructor-arg value="cn=LDAP-STACK,ou=apps,o=lds" /></bean><bean id="securityConnectionPassword" class="java.lang.String"> <constructor-arg value="password1" /></bean>

Page 28: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Stack Utils namespace handler (stack-utils:null)• Additionally, sometimes you would like the value

to be null in a test– This can be accomplished with a Stack provided Xml-

schema based configuration

– For more information:• http://code.lds.org/maven-sites/stack/module.html?

module=spring-utils• http://code.lds.org/maven-sites/stack/module.html?

module=spring-utils/xsddoc/

<stack-util:null id="securityConnectionUrl" /><stack-util:null id="securityConnectionDN" /><stack-util:null id="securityConnectionPassword" />

Page 29: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Another example

• The application bean definition file

• The test bean definition file

<stack-db:data-source jndi-name="jdbc/default/DataSource"/>

<stack-db:data-source driver-class="org.h2.Driver" url="jdbc:h2:mem:stack-starter;MODE=Oracle" user="" password="" override="true" db-env="EMBEDDED"/>

Page 30: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Testing with a Database

• Suppose you wanted to use a database to test– Normally

• You would add data, run the test, and then clean it up

– Spring provides transactional support • Data from the test automatically rolls back after the test

– Must extend AbstractTransactionalTestNGSpringContextTests

• Must specify a transaction manager in your bean definition

– Additional documentation:• http://static.springsource.org/spring/docs/3.0.x/spring-

framework-reference/html/testing.html#testcontext-tx

Page 31: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Spring Provides Useful Testing Stubs

• Lastly Spring provides many useful stubs (mock objects)– JNDI– Servlet API– These can save a lot of code– Often more usable that dynamic mock objects

• For further information:– http://static.springsource.org/spring/docs/3.0.x/

spring-framework-reference/html/testing.html#mock-objects

Page 32: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Lab 3: Spring Testing Integration

https://tech.lds.org/wiki/Intermediate_Spring#Lab_3_Spring_Testing_Inte

gration

Page 33: Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions Prerequisites – Introduction to Java Stack – Basic

Credit where credit is due

• http://springsource.org• Spring Recipies 2nd Edition (Gary Mak, Josh Long

and Daniel Rubio)