Internationalization and the Java Stack Part 1 Matt Wheeler.
Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions...
-
Upload
alexandra-devere -
Category
Documents
-
view
217 -
download
0
Transcript of Intermediate Spring Matt Wheeler. Notes This is a training NOT a presentation Please ask questions...
Intermediate SpringMatt Wheeler
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)
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)
Overview
• Advanced Injection• Providers• Spring EL• Additional Injection Annotations
• Application Context web integration• Testing framework
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
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;…}
Provider Demo
DEMO
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
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"/>
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.
Lab 1: Providers
https://tech.lds.org/wiki/Intermediate_Spring#Lab_1_Advanced_Injection
Web Context Listener
• Loading application contexts in a web environment
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);
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
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>
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
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(); }}
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
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(); }}
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
Lab 2: Web Context Listener
https://tech.lds.org/wiki/Intermediate_Spring#Lab_2_Web_Context_Liste
ner
Spring Testing
• Spring promotes testing in two prominent ways– Making the code more testable– Proving a testing framework
Testable Code
• Dependency injection decouples code from the container– POJOs are normally easier to test
• Dependencies are clearly defined– Allows you to swap implementations
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)
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
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 {//…}
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>
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" />
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"/>
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
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
Lab 3: Spring Testing Integration
https://tech.lds.org/wiki/Intermediate_Spring#Lab_3_Spring_Testing_Inte
gration
Credit where credit is due
• http://springsource.org• Spring Recipies 2nd Edition (Gary Mak, Josh Long
and Daniel Rubio)