matt wheeler n.
Skip this Video
Loading SlideShow in 5 Seconds..
Matt Wheeler PowerPoint Presentation
Download Presentation
Matt Wheeler

Matt Wheeler

137 Vues Download Presentation
Télécharger la présentation

Matt Wheeler

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Intermediate Spring Matt Wheeler

  2. 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)

  3. 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)

  4. Overview • Advanced Injection • Providers • Spring EL • Additional Injection Annotations • Application Context web integration • Testing framework

  5. 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

  6. 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? @Component public class Farm { @Inject @Named("prototypeRabbit") private Rabbit prizeRabbit; … }

  7. Provider Demo DEMO

  8. 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: •

  9. 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"/>

  10. Additional Injection Annotations • Many additional injection annotations • Please refer to the Spring documentation here: •

  11. Lab 1: Providers

  12. Web Context Listener • Loading application contexts in a web environment

  13. 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"); SomeBeansomeBean = context.getBean(SomeBean.class);

  14. 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

  15. 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>

  16. 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

  17. Application Context and Servlet • For the given servlet configuration (web.xml) • Application Context accessed as follows: <servlet> <servlet-name>servlet</servlet-name> <servlet-class></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 ApplicationContextapplicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); SomeBeansomeBean = (SomeBean) applicationContext.getBean(SomeBean.class); someBean.printSomething(); } }

  18. 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

  19. Utilizing a Spring Request Handler • The configuration: <!– web.xml --> <servlet> <servlet-name>trainingHandler</servlet-name> <servlet-class></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 SomeBeansomeBean; public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { someBean.printSomething(); } }

  20. 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

  21. Lab 2: Web Context Listener

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

  23. Testable Code • Dependency injection decouples code from the container • POJOs are normally easier to test • Dependencies are clearly defined • Allows you to swap implementations

  24. 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)

  25. 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

  26. 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 { //… }

  27. 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>

  28. 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: • • <stack-util:null id="securityConnectionUrl" /> <stack-util:null id="securityConnectionDN" /> <stack-util:null id="securityConnectionPassword" />

  29. 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"/>

  30. 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: •

  31. 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: •

  32. Lab 3: Spring Testing Integration

  33. Credit where credit is due • • Spring Recipies 2nd Edition (Gary Mak, Josh Long and Daniel Rubio)