1. Create bean definitions (from xml or annotations, or, …)

Intermediate Spring
Matt Wheeler
Notes
• This is a training NOT a presentation
• Please ask questions
• Prerequisites
– Introduction to Java Stack
– Basic Java and XML skills
– Installed LdsTech IDE (or other equivalent – good luck
there ;)
Overview
• Bean lifecycle
• Xml Configuration Extensions (namespace
handlers)
• Lifecycle hooks
• JSR 250
• Bean post processors
• Spring Annotations
• JSR 330 Annotations (@Inject, @Named)
Review
• Last time we went over
– Bean definitions
– Dependency Injection (DI) and Inversion of Control
(IoC)
– Application context
– Bean scopes
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");
SomeBean someBean = context.getBean(SomeBean.class);
someBean.callMethod();
Spring Bean Lifecycle
1. Create bean definitions (from xml or
annotations, or, …)
2. Instantiate beans using the definitions
3. Set bean dependencies (values and bean
references) on the newly instantiated beans
4. Initialization
5. Deliver bean to requester for use
6. On container shutdown call destruction callback
method
Xml Configuration Extension
•
•
•
•
•
Also called namespace handlers
Shorten bean definition configuration
Provide easily reusable definitions
Self documenting
More readable
Spring Xml Configuration Extensions
Schema
Description / Documentation
util
Create non-anonymous collection types that can be referenced by id
http://static.springsource.org/spring/docs/3.0.x/spring-frameworkreference/html/xsd-config.html#xsd-config-body-schemas-util
jee
Elements such as jndi support / ejb shortcuts
http://static.springsource.org/spring/docs/3.0.x/spring-frameworkreference/html/xsd-config.html#xsd-config-body-schemas-jee
lang
Expose beans written in another language like JRuby or Groovy
http://static.springsource.org/spring/docs/3.0.x/spring-frameworkreference/html/xsd-config.html#xsd-config-body-schemas-lang
jms
Deal with configuring JMS-related beans
http://static.springsource.org/spring/docs/3.0.x/spring-frameworkreference/html/xsd-config.html# xsd-config-body-schemas-jms
tx
Transaction support
http://static.springsource.org/spring/docs/3.0.x/spring-frameworkreference/html/xsd-config.html# xsd-config-body-schemas-tx
Xml Configuration Extensions (cont.)
Schema
Descirption / Documentation
aop
Helpers for Spring’s aspect oriented programming mechanisms
http://static.springsource.org/spring/docs/3.0.x/spring-frameworkreference/html/xsd-config.html# xsd-config-body-schemas-aop
context
Configuration relation to the application context plumbing
http://static.springsource.org/spring/docs/3.0.x/spring-frameworkreference/html/xsd-config.html# xsd-config-body-schemas-context
tools
Configuration for adding tooling specific meta-data
http://static.springsource.org/spring/docs/3.0.x/spring-frameworkreference/html/xsd-config.html# xsd-config-body-schemas-tool
security
Provides elements for web security configuration
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/nsconfig.html
mvc
Provides interceptors, view-conroller, …..
http://static.springsource.org/spring/docs/3.0.x/spring-frameworkreference/html/mvc.html#mvc-config
Example
• You have options
<mvc:annotation-driven validator="validator" />
• Or
<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>
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>
Another Example
• Let us utilize 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">
<!-- definitions here -->
</beans>
<!-- creates a java.util.List instance with the supplied values -->
<util:list id="alphaGroups">
<value>abc</value>
<value>def</value>
<value>ghi</value>
<value>jkl</value>
</util:list>
<bean id="alphaGroups" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list>
<value>abc</value>
<value>def</value>
<value>ghi</value>
<value>jkl</value>
</list>
</property>
</bean>
Xml Configuration Extension architecture
• Pieces of namespace handlers
• Create an xml schema that describes allowable
elements
• Write a namespace handler
• Code a BeanDefinitionParser
– Parses the defined xml and adds any necessary beans
into the configuration
For Example
Add a parser example here
• Bottom line
– Namespace handlers are backed by code
• The code supplements bean configuration and is
a lot more than meets the eye
DEMO
Lab 1: Xml Configuration Extensions
https://tech.lds.org/wiki/Intermediate_Spring#Lab
_1_Xml_Configuration_Extensions
JSR 250 Annotations
Hooking into the Lifecycle
• Define init-method in bean definition
<bean id=”whatever” init-method=”init” class=”org.lds.training.SomeBean” />
• The associated bean
public class SomeBean {
public void init() {
//some initialization code
}
}
• The init method is called after the bean had been
initialized an all properties set
Spring Bean Lifecycle Review
1. Create bean definitions (from xml or
annotations, or, …)
2. Instantiate beans using the definitions
3. Set bean dependencies (values and bean
references) on the newly instantiated beans
4. Initialization
5. Deliver bean to requester for use
6. On container shutdown call destruction callback
method
Annotate the Class
• JSR 250 annotations provides @PostConstruct
annotation for bean initialization
public class SomeBean {
@PostConstruct
public void init() {
// do some initialization work
}
}
• There is likewise an @PreDestroy counterpart
– Called just before the bean is destroyed
– Allows for cleanup of resources
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>
Lab 2: JSR 250 Annotations
https://tech.lds.org/wiki/Intermediate_Spring#Lab
_2_JSR_250_Annotations
Spring Annotations
• We have seen how to use annotations to call an
init method during initialization
• Wouldn’t it be nice if didn’t need to define even
the beans themselves in xml at all?
– We will need something to scan the classes for
annotations and register bean definitions
Welcome component-scan
• component-scan element in context schema
– Scans classpath searching for matching beans
• Registers bean definitions 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/springframework-reference/html/beans.html#beans-scanning-filters
– annotation
– assignable
– aspectj
– regex
– cutsom
Bean Lifecycle and Component Scan
1. Create bean definitions (from xml or
annotations, or, …)
2. Instantiate beans using the definitions
3. Set bean dependencies (values and bean
references) on the newly instantiated beans
4. Initialization
5. Deliver bean to requester for use
6. On container shutdown call destruction callback
method
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="org\.lds\.training\..*abc.*" type="regex"/>
<context:exclude-filter expression=“org.lds.training.Animal" type="assignable"/>
</context:component-scan>
</beans>
Naming
• What id will be given for beans that are
registered?
• By default it is the class name with the first letter
lower cased
– For example, a class named Rabbit would result in a
bean definition with id=“rabbit”
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 with Spring
• Annotation scanning
Spring Annotations
• Spring provides stereotype annotations to help
identify a bean’s role the application architecture
– @Service – denotes application services
– @Controller – denotes a view layer components
– @Component – the most general stereotype
annotation – denotes any class to be managed by
Spring
– @Repositoy – most often used to demarcate DAOs
– You can also create your own custom stereotype
annotations
For Example
• In a given application context you may want to have the
scanner
– Register beans annotated with your custom annotation
– But not register definitions for beans annotated with @Service
<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>
Naming
• So how does annotation scanning help naming?
– The following will still register a bean with id=“rabbit”
@Component
public class Rabbit {
}
– But, this will register a bean with id=“crazyRabbit”
@Component("crazyRabbit")
public class Rabbit {
}
The Main Point
• All this to tell you that now you can create a bean
automatically without defining it in xml
• That is to say, the following are basically
equivalent in function
<bean id="something" class="org.lds.training.SomeBean" />
@Component("something")
public class SomeBean {
}
Scope
• But what about scope
– i.e. what is the equivalent annotation for specifying a
scope of prototype
<bean id="something" class="org.lds.training.SomeBean" scope="prototype"/>
– @Scope("prototype")
@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")
– @Scope("globalSession")
Putting it all together
• Xml definition
<bean id="turkey" class="org.lds.training.Turkey" scope="prototype">
• Equivalent annotation definition
@Component
@Scope("prototype")
public class Turkey {
}
Lab 3: Spring Annotations
Credit where credit is due
• http://springsource.org
• Spring Recipies 2nd Edition (Gary Mak, Josh Long
and Daniel Rubio)