1 / 44

Matt Wheeler

Introduction to Spring (part 2). Matt 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 (part 1) Installed LDSTech IDE (or other “equivalent”). Review.

burt
Download Presentation

Matt Wheeler

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Introduction to Spring (part 2) 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 (part 1) • Installed LDSTech IDE (or other “equivalent”)

  3. Review • Last time we went over • Bean definitions • Dependency Injection (DI) and Inversion of Control (IoC) • Application context • Bean scopes

  4. Review • Bean definition (beans.xml) <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean class="org.lds.training.SomeBean" /> </beans> • Application Context ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); SomeBeansomeBean = context.getBean(SomeBean.class); someBean.callMethod();

  5. Overview • 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)

  6. Spring Bean Lifecycle 1. Bean definitions created/registered (from xml or annotations, or, …) 2. Beans instantiated using the definitions 3. Dependencies set (values and bean references) on the newly instantiated beans 4. Bean initialization 5. Beans delivered to requester for use 6. Destruction callback method called at container shutdown

  7. XML Schema-based Configuration • Also called namespace handlers • Shorten bean definition configuration • Provide easily reusable definitions • Self documenting • More readable • NOTE: Takes place in the first phase of the bean lifecycle (i.e. while xml files are being parsed)

  8. XML Schema-based Configuration • Example namespace handler • Basically equivalent configuration <mvc:annotation-driven validator="validator" /> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="order" value="0"/> <property name="useDefaultSuffixPattern" value="false"></property> </bean> <bean class="org.springframework.web.servlet.handler.MappedInterceptor"> <constructor-arg value="null"></constructor-arg> <constructor-arg> <bean class="org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor"> <constructor-arg> <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean"></bean> </constructor-arg> </bean> </constructor-arg> </bean>

  9. Wait that’s not all And this <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="webBindingInitializer"> <bean id="webBindingInitializer" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <property name="validator" ref="validator" /> <property name="conversionService"> <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" /> </property> </bean> </property> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="writeAcceptCharset" value="false" /> </bean> <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean> <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean> <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></bean> <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean> </list> </property> </bean>

  10. Another Example • Utilizing a namespace handler <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">   <!-- creates a java.util.Set instance with the supplied values --> <util:set id="alphaGroups"> <value>abc</value> <value>def</value> <value>ghi</value> <value>jkl</value> </util:set> </beans> <bean id="alphaGroups" class="org.springframework.beans.factory.config.SetFactoryBean"> <property name="sourceSet"> <set> <value>abc</value> <value>def</value> <value>ghi</value> <value>jkl</value> </set> </property> </bean>

  11. Demo DEMO

  12. Spring XML Schema-based Configurations

  13. XML Schema-based Configuration (cont.)

  14. XML Schema-based Configuration arch. • Parts of XML Schema-based configuration • Xml schema that describes allowable elements • Namespace handler (Java code) • BeanDefinitionParser (Java code) • Parses the defined xml and adds any necessary beans into the configuration • Bottom line • Namespace handlers are backed by code • The code supplements bean configuration and is often a lot more than meets the eye

  15. Bean Definition Parsers • Let’s look at an example <!– configuration element in bean definition file --> <abc:something some-attribute="true" /> <!– backing bean definition parser code --> public class SomeBeanDefinitionParser implements BeanDefinitionParser { public AbstractBeanDefinitionparse(Elementelement, ParserContextparserContext) { CompositeComponentDefinitioncompositeDef = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element)); parserContext.pushContainingComponent(compositeDef); BeanDefinitionBuildersomeBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SomeBean.class); if (Boolean.parseBoolean(element.getAttribute("some-attribute"))) { SomeBeanDefinition.addPropertyValue("someProperty", "abc"); } … }

  16. Lab 1: XML Schema-based Configuration https://tech.lds.org/wiki/Introduction_to_Spring_(part2)#Lab_1_XML_Schema-based_Configuration

  17. Bean Initialization

  18. Spring Bean Lifecycle 1. Bean definitions created/registered (from xml or annotations, or, …) 2. Beans instantiated using the definitions 3. Dependencies set (values and bean references) on the newly instantiated beans 4. Bean initialization 5. Beans delivered to requester for use 6. Destruction callback method called at container shutdown

  19. Hooking into the Lifecycle • Assume the following class • Define init-method to be called • The init method is called after the bean has been initialized and all properties set public class SomeBean { public void init() { //some initialization code } } <bean id="whatever" init-method="init" class="org.lds.training.SomeBean" />

  20. JSR 250 Common Annotations • The goal of JSR 250 was to come up with a standard set of annotations to accomplish common use cases in Java • The annotations are outlined here: http://en.wikipedia.org/wiki/JSR_250 • We will only be focusing on a tiny subset of these annotations in order to replace our init-method functionality

  21. Annotate the Class • JSR 250 annotations provides @PostConstruct annotation for bean initialization • There is likewise an @PreDestroy counterpart • Called just before the bean is destroyed • Allows for cleanup of resources public class SomeBean { @PostConstruct public void init() { // do some initialization work } }

  22. Configure Annotation Handling • Specify annotation handlers (bean post processors) <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" /> </beans> <!– or --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:context=http://www.springframework.org/schema/context xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config /> </beans>

  23. Lab 2: Bean Initialization https://tech.lds.org/wiki/Introduction_to_Spring_(part2)#Lab_2_Bean_Initialization

  24. Spring Component Annotations • We have seen how to use annotations to call an init method during initialization • Wouldn’t it be nice if we didn’t need to define even the beans themselves in xml at all? • To accomplish this, we would need something to scan the classes for annotations and register bean definitions

  25. Welcome component-scan • component-scan element in context schema • Scans classpath searching for matching beans • Registers bean definitions for matching classes • Can specify an include filter and/or exclude filter • You can also assign a filter type for a targeted search • http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-scanning-filters • annotation • assignable • regex • custom

  26. Bean Lifecycle and Component Scan 1. Bean definitions created/registered (from xml or annotations, or, …) 2. Beans instantiated using the definitions 3. Dependencies set (values and bean references) on the newly instantiated beans 4. Bean initialization 5. Beans delivered to requester for use 6. Destruction callback method called at container shutdown

  27. For Example • This configuration will (for the given packages): • Register bean definitions for all classes with “abc” in their names • Not register beans for any classes that extend / implement Animal <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="org.lds.training,org.lds.another"> <context:include-filter expression=".*abc.*" type="regex"/> <context:exclude-filter expression=“org.lds.training.Animal" type="assignable"/> </context:component-scan> </beans>

  28. Naming • What id will be given for beans that are registered? • By default it is the class name with the first letter lower cased • Package is dropped from the name • For example, a class named Rabbit would result in a bean definition with id=“rabbit”

  29. Annotation Scanning • What do we do if: • The default naming is not acceptable • Difficult to come up with a pattern that matches only the beans that we want registered in Spring • What if we don’t want scope of singleton • We can employ annotations and only register definitions for classes that are appropriately annotated

  30. Spring Component Annotations • Spring provides stereotype annotations to identify a bean’s role in the app. architecture • @Service – denotes application services • @Controller – denotes view layer components • @Component – most general stereotype annotation, denotes any class to be managed by Spring • @Repository – most often used to demarcate DAOs • You can also create your own custom stereotype annotations • http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-stereotype-annotations

  31. For Example • In a given application context you may want to have the scanner selectively register definitions • Register beans annotated with your custom annotation • Once include is specified defaults are disabled <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="org.lds.training"> <context:include-filter expression="org.lds.training.Custom" type="annotation"/> <context:exclude-filter expression="org.springframework.stereotype.Service" type="annotation"/> </context:component-scan> </beans>

  32. Naming • So how does annotation scanning help naming? • The following will still register a bean with id=“rabbit” • But, this will register a bean with id=“crazyRabbit” • I.e. the annotations allow you to provide a specific name for the given bean to the bean definition parser @Component public class Rabbit { } @Component("crazyRabbit") public class Rabbit { } <!– equivalent to the following xml bean definition --> <bean id="crazyRabbit" class="org.lds.training.Rabbit" />

  33. Scope • But what about scope • What is the equivalent annotation for specifying a scope of prototype • @Scope("prototype") <bean id="something" class="org.lds.training.SomeBean" scope="prototype"/>

  34. @Scope • Be sure to use org.springframework.context.annotation.Scope • Not javax.inject.Scope • Possible values: • @Scope or @Scope("singleton") • @Scope("prototype") • @Scope("request") • @Scope("session")

  35. Putting it all together • All this to tell you that now you can create bean definitions automatically without defining them in xml • Xml definition • Equivalent annotation definition <bean id="turkeyLurkey" class="org.lds.training.Turkey" scope="prototype"> @Component(“turkeyLurkey“) @Scope("prototype“) public class Turkey { }

  36. Lab 3: Spring Component Annotations https://tech.lds.org/wiki/Introduction_to_Spring_(part2)#Lab_3_Spring_Component_Annotations

  37. DI Annotations (JSR 330) • Now that we can create bean definitions how do we specify injection • Luckily the JSR 330 specification defines some standard annotations for specifying injection

  38. Dependency • JSR 330 annotations require you to include the following dependency: • Don’t be alarmed by the unorthodox version value • It is correct as of this writing <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>

  39. Dependency Injection Annotations • To inject beans we have the following new annotations • @Inject – inject bean references by type • @Named – modify injection by specifying a named resource

  40. @Inject • @Inject can be used almost anywhere //on a member variable @Inject private Rabbit rabbit; //on a constructor @Inject public Farm(Rabbit prizeRabbit) {…} //on a setter method @Inject public void setPrizeRabbit(Rabbit rabbit) { this.rabbit = rabbit; } //if you can’t inject all of them by type you could use @Named to narrow to a single match @Inject public void anyMethod(Chicken chicken, @Named("prototypeRabbit") Rabbit rabbit, Duck duck) { … } //on collections (will inject all beans in the application context of the specified type) @Inject private Rabbit[] rabbits; @Inject private List<Rabbit> rabbits; //will contain all beans with the given type and the bean name as the key @Inject private Map<String, Rabbit> rabbits;

  41. @Inject (cont) • By default injection injects by type • Finds any registered instances of the type for the annotated type • What if you have two targets of the same type? • You can specify by name • Downside is that this is no longer type safe • Only referenced by a String • Could employ a Qualifier to remain type safe • http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-autowired-annotation-qualifiers @Inject @Named("prototypeRabbit") private Rabbit prizeRabbit;

  42. Putting it all together • Xml definition • Somewhat equivalent annotation definition <bean id="billysFarm" class="org.lds.training.Farm"> <constructor-arg name="turkey" ref="turkey" /> </bean> @Component public class Turkey { … } @Component(" billysFarm") public class Farm { private Turkey turkey; @Inject public Farm(Turkey turkey) { this.turkey = turkey; } }

  43. Lab 4: JSR 330 (DI) Annotations https://tech.lds.org/wiki/Introduction_to_Spring_(part2)#Lab_4_DI_Annotations_(JSR_330)

  44. Credit where credit is due • http://springsource.org • http://en.wikipedia.org/wiki • Spring Recipies 2nd Edition (Gary Mak, Josh Long and Daniel Rubio)

More Related