# Spring Framework
# Introduction
docs
- Spring Framework
- AOP
- Spring Boot
philosophy
- beans — Java objects that perform business logic, execute tasks, persist and retrieve persisted data, respond to HTTP requests, and more
- config — XML-based, annotations, and JavaConfig-based approaches for configuring beans
- can used as meta annotation — for example any annotation that is annotated with
@Componentbecomes a component annotation, and so forth
- can used as meta annotation — for example any annotation that is annotated with
-Aware—set-methods for callbacksorg.springframework.context.EnvironmentAware—void setEnvironment(Environment environment)
-Capable,-edBean—get-methodsorg.springframework.core.env.EnvironmentCapable—Environment getEnvironment()
Configurable-:ConfigurableApplicationContext,ConfigurableBeanFactory— typically implement to configureListable-:ListableBeanFactory— can enumerate, rather than attempting bean lookup by name one by one- parameters
boolean requiredin annotation parameter —Exceptionornulljava.util.Optionalas method parameter — equivalent torequiredsetfalse
- AOP — JDK proxy or CGLIB subclassing; CGLIB proxy instance is created through Objenesis, so constructor is not called twice since 4.0
# Utils
create a new Spring project
- official docs: Getting Started · Building a RESTful Web Service (opens new window)
- Spring Initializr (opens new window)
- metadata
groupId— Java package likeartifactId— use hyphen as delimiters
- create a project using maven
mvn archetype:generate -DgroupId=com..todo -DartifactId=todo -Dversion=0.0.1-SNAPSHOT -DinteractiveMode=false -DarchetypeArtifactId=maven-archetype-webapp - maven configuration
# Servlet
maven artifact
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </dependency>- docs
- javax.servlet.http (Java Servlet 4.0) (opens new window)
- web.xml Reference Guide for Tomcat - Metawerx Java Wiki (opens new window)
- JSR-000369 Java Servlet 4.0 Specification Final Release (opens new window)
- The Java Community Process(SM) Program - JSRs: Java Specification Requests - detail JSR# 369 (opens new window)
- docs
web.xml<web-app> <display-name>Hello World Application</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file>index.html</welcome-file> </welcome-file-list> <error-page> <error-code>500</error-code> <location>/errors/servererror.jsp</location> </error-page> </web-app>interface javax.servlet.ServletContainerInitializer— support code-based configuration of the servlet container using Spring's WebApplicationInitializer SPI as opposed to (or possibly in combination with) the traditionalweb.xml-based approachvoid onStartup(Set<Class<?>> c, ServletContext ctx)— on the startup of the applicationc— classes in@javax.servlet.annotation.HandlesTypes::valueannotated on the implementation,nullif not annotated with@HandlesTypesorvalueis empty
- SPI — implementations as service provider in
META-INF/servicesinside JAR files org.springframework.web.SpringServletContainerInitializer— Spring's implementation, defaults to delegating to allWebApplicationInitializer::onStartupwithservletContext@HandlesTypes(WebApplicationInitializer.class) public class SpringServletContainerInitializer implements ServletContainerInitializer
# HTTP Servlet, ServletConfig and ServletContext
javax.servlet.http.HttpServlet— an abstract class to be subclassed to create an HTTP servletpublic abstract class HttpServlet extends GenericServletpublic abstract class GenericServlet extends Object implements Servlet, ServletConfig, Serializable- dispatch
void service(ServletRequest req, ServletResponse res)— dispatches client requests to the protected oneprotected void service(HttpServletRequest req, HttpServletResponse resp)— dispatches HTTP requests to thedoXXXmethods
- HTTP methods,
throws ServletException, IOExceptionprotected void doDelete(HttpServletRequest req, HttpServletResponse resp)protected void doGet(HttpServletRequest req, HttpServletResponse resp)protected long getLastModified(HttpServletRequest req)
doHead,doOptions,doPost,doPut,doTrace
- lifecycle, for override
void init()— called when the first request arrives for this servlet if the order is not specified in<load-on-startup>; called invoid init(ServletConfig config),ServletConfigandServletContextare already availablevoid destroy()
- get config
ServletConfig getServletConfig()ServletContext getServletContext()interface javax.servlet.ServletConfig— configures inweb.xmlString getInitParameter(String name)Enumeration<String> getInitParameterNames()ServletContext getServletContext()String getServletName()
- dispatch
config
HttpServlet— inweb.xmlor by annotations@javax.servlet.annotation.WebServlet@Target(value=TYPE) public @interface WebServletboolean asyncSupported,String description,String displayName,WebInitParam[] initParams,String largeIcon,int loadOnStartup,String name,String smallIcon,String[] urlPatterns,String[] value
@MultipartConfig, see after- in
web.xml— the same class can have multiple instances with different names<servlet> <servlet-name>comingsoon</servlet-name> <servlet-class>mysite.server.ComingSoonServlet</servlet-class> <!-- <load-on-startup>1</load-on-startup> --> <init-param> <param-name>teamColor</param-name> <param-value>red</param-value> </init-param> <init-param> <param-name>bgColor</param-name> <param-value>#CC0000</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>comingsoon</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping><url-pattern>/</url-pattern>— when mapping to the application root, use/instead of/*, avoiding sending even internal JSP requests to the Servlet<multipart-config>, see after- static server — use the
defaultservlet, implementation isorg.apache.catalina.servlets.DefaultServletfor Tomcat<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/resources/*</url-pattern> <url-pattern>*.css</url-pattern> <url-pattern>*.js</url-pattern> <url-pattern>*.png</url-pattern> <url-pattern>*.gif</url-pattern> <url-pattern>*.jpg</url-pattern> </servlet-mapping>
interface javax.servlet.ServletContext— a set of methods that a servlet uses to communicate with its servlet container, one context per "web application" per JVM- context parameter
<context-param> <param-name>settingOne</param-name> <param-value>foo</param-value> </context-param> <context-param> <param-name>settingTwo</param-name> <param-value>bar</param-value> </context-param>String getInitParameter(String name),Enumeration<String> getInitParameterNames()boolean setInitParameter(String name, String value)
- registration
addFilteraddListeneraddServlet
- context parameter
interface javax.servlet.AsyncContext— initialized byServletRequest::startAsyncvoid start(Runnable run)boolean hasOriginalRequestAndResponse()
# HTTP Servlet Request and Response
javax.servlet.http.HttpServletRequestpublic interface HttpServletRequest extends ServletRequest- get request info — headers, URL and URL segments, sessions and cookies and more
String getParameter(String name)and more — query string or posted form data; when latter,getInputStream()used internally, later call togetInputStream()orgetReaderwill throwIllegalStateExceptionBufferedReader getReader(),ServletInputStream getInputStream()javax.servlet.ServletInputStream— can haveReadListenerto notify when possible to read
- file upload, or the
multipart/form-dataMIME typePart getPart(String name),Collection<Part> getParts()@javax.servlet.annotation.MultipartConfig— annotated instances of theServletexpect requests that conform to themultipart/form-dataMIME typeint fileSizeThreshold-long maxFileSize-long maxRequestSizeString location— file store location, can leave to container to determine
- serve HTML files, JSP files — include or forward to another resource (servlet, JSP file, or HTML file) from a request
RequestDispatcher getRequestDispatcher(String path)RequestDispatcher::forward,RequestDispatcher::include
- async
startAsync— can wrap original request and responseisAsyncStarted-isAsyncSupported-getAsyncContext
- customized implementation —
javax.servlet.ServletRequestWrapper,javax.servlet.http.HttpServletRequestWrapperfor extending
- get request info — headers, URL and URL segments, sessions and cookies and more
sessions
interface javax.servlet.http.HttpSession— attribute getters, setters and more- session types
- session in URL path, insecure and obsolete —
HttpServletResponse::encodeURL,HttpServletResponse::encodeRedirectURL - cookie session
- SSL session ID as HTTP session ID, unreliable
- session in URL path, insecure and obsolete —
HttpServletRequest::getSession— get or create- in clustered environment — use sticky sessions or session replication
- session config in
web.xml<session-config> <session-timeout>30</session-timeout> <cookie-config> <name>JSESSIONID</name> <domain>example.org</domain> <path>/shop</path> <comment><![CDATA[Keeps you logged in. See our privacy policy for more information.]]></comment> <http-only>true</http-only> <secure>false</secure> <max-age>1800</max-age> </cookie-config> <tracking-mode>COOKIE</tracking-mode> <tracking-mode>URL</tracking-mode> <tracking-mode>SSL</tracking-mode> <distributable/> <!-- enabling session replication --> </session-config>
javax.servlet.http.HttpServletResponsepublic interface HttpServletResponse extends ServletResponseboolean isCommitted()— a committed response has already had its status code and headers written- status code and redirect
static intfields- status code setter and getter
sendError— can optionally specify an error message
sendRedirect
- response body
ServletOutputStream getOutputStream(),PrintWriter getWriter()- buffer related methods
javax.servlet.ServletOutputStreamabstract void setWriteListener(WriteListener writeListener)
- response headers
- MIME type related methods
- charset and locale getters and setters
void addCookie(Cookie cookie)- header setters, adders — call before response body stream getter
setContentLength,setContentLengthLong— should leave to container
- customized implementation —
javax.servlet.ServletResponseWrapper,javax.servlet.http.HttpServletResponseWrapperfor extending
# Servlet Listeners
config listeners
- in
web.xml—<listener> ServletContext::addListener— called within a registeredServletContextListener::contextInitializedorServletContainerInitializer::onStartup@javax.servlet.annotation.WebListener— any annotated class must implement one or more of theServletContextListener,ServletContextAttributeListener,ServletRequestListener,ServletRequestAttributeListener,HttpSessionListener,HttpSessionAttributeListener, orHttpSessionIdListener@Target(value=TYPE) public @interface WebListener
- in
listeners — interfaces to be implemented, extending
java.util.EventListenerjavax.servlet.ServletContextListenerdefault void contextDestroyed(ServletContextEvent sce)default void contextInitialized(ServletContextEvent sce)
javax.servlet.http.HttpSessionAttributeListenerjavax.servlet.http.HttpSessionBindingListener— no config required, event triggered when set or removed from aHttpSessionor session expiring- more
# Servlet Filters
javax.servlet.Filter— acts on a request like a servlet, but can allow the handling of the request to continue with other filters or servlets- use case — Authentication Filters, Logging and Auditing Filters, Data compression Filters, Encryption Filters, Tokenizing Filters, Mime-type chain Filter, error handling filters
- lifecycle
default void init(FilterConfig filterConfig)— called on application startup, after initialization ofServletContextListenersdefault void destroy()
- filter chain
- when request come in — container -> filter 1 -> filter 2 -> ... -> filter n -> container -> servlet
- when returning response — container <- filter 1 <- filter 2 <- ... <- filter n <- container <- servlet
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)FilterChain::doFilter— call next filter in the chain, otherwise the chain is interrupted
- mapping
- to URL — ordered before servlet mapping
- to servlets
- specify request types
- normal requests
RequestDispatcher::forwarded andRequestDispatcher::includeed requests — handled internally as a separate request- error requests
AsyncContextdispatched requests
filter config
@javax.servlet.annotation.WebFilter— cannot determine order; alternatively useServletContext::addListenerinServletContextListener::contextInitializedorServletContainerInitializer::onStartupand the order depends on the call@Target(value=TYPE) public @interface WebFilterdescription,displayName,filterName,smallIcon,largeIconString[] servletNamesString[] urlPatternsDispatcherType[] dispatcherTypes—ASYNC,ERROR,FORWARD,INCLUDE,REQUESTWebInitParam[] initParamsboolean asyncSupported
interface javax.servlet.FilterConfig—getFilterName,getServletContext,getInitParameter,getInitParameterNames- in
web.xml, in the order of presence<filter> <filter-name>logSpecial</filter-name> <filter-class>mysite.server.LogFilterImpl</filter-class> <init-param> <param-name>logType</param-name> <param-value>special</param-value> </init-param> </filter> <filter-mapping> <filter-name>logSpecial</filter-name> <url-pattern>*.special</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>ASYNC</dispatcher> </filter-mapping> <filter-mapping> <filter-name>logSpecial</filter-name> <servlet-name>comingsoon</servlet-name> </filter-mapping>
# Application Context
# Spring Container
spring container
interface org.springframework.beans.factory.BeanFactory- root interface for accessing a Spring bean containergetBeanmethod — get a bean with type, name and/or other args as parameter(s)getBeanProvidermethod — lazy load a bean, see@Lazy- other methods
interface org.springframework.context.ApplicationContext— application context, manages a set of beans, which are eligible for dependency injection, message notification, scheduled method execution, bean validation, and other crucial Spring servicespublic interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolverorg.springframework.beans.factory.ListableBeanFactory—BeanFactorybut return iterable objects containing beansorg.springframework.context.ApplicationEventPublisher— the ability topublishEventto registered listenersorg.springframework.core.io.ResourceLoader— the ability to load file or URL resources in a generic fashionorg.springframework.core.io.support.ResourcePatternResolver— getResourcefor location patterns
org.springframework.context.MessageSource— the ability to resolve messages, supporting internationalizationorg.springframework.beans.factory.HierarchicalBeanFactory— can have inheritance hierarchy
application context derivations
org.springframework.context.ConfigurableApplicationContext—ApplicationContextbut configurablepublic interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeableorg.springframework.context.Lifecycle— withstart(),stop(),isRunning()void setParent(ApplicationContext parent)void registerShutdownHook()- more
org.springframework.web.context.WebApplicationContext— withgetServletContext()org.springframework.web.context.ConfigurableWebApplicationContext
application context implementations
org.springframework.context.annotation.AnnotationConfigRegistry— annotation config application contextsorg.springframework.context.annotation.AnnotationConfigApplicationContextorg.springframework.web.context.support.AnnotationConfigWebApplicationContext
org.springframework.context.support.AbstractRefreshableConfigApplicationContext— base class for XML-based application context implementationsorg.springframework.context.support.ClassPathXmlApplicationContextorg.springframework.context.support.FileSystemXmlApplicationContextorg.springframework.context.support.XmlWebApplicationContext
# Configure Contexts
bootstrap application context
public static void main(final String[] args) throws Exception { ApplicationContext ctx = new ClassPathXmlApplicationContext("scripting/beans.xml"); Messenger messenger = ctx.getBean("messenger", Messenger.class); System.out.println(messenger); }public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(MyServiceImpl.class, Dependency1.class, Dependency2.class); MyService myService = ctx.getBean(MyService.class); myService.doStuff(); }public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class, OtherConfig.class); ctx.register(AdditionalConfig.class); ctx.refresh(); MyService myService = ctx.getBean(MyService.class); myService.doStuff(); }programmatic configuration
AnnotationConfigApplicationContext- post processors — when using
AnnotationConfigApplicationContext, annotation config processors are always registered - constructors with parameters — methods combined
AnnotationConfigApplicationContext(Class<?>... componentClasses)AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory)AnnotationConfigApplicationContext(String... basePackages)
void register(Class<?>... componentClasses)— register one or more component classes (typically@Configurable) to be processedvoid scan(String... basePackages)
- post processors — when using
ConfigurableApplicationContext::refresh— load or refresh the persistent representation of the configuration, required to be called after above two methods- see
@Configurationfor configuration classes
configure beans in application context XML configurations, like
/WEB-INF/servlet-context.xml- example
<beans> <!-- namespace definitions omitted --> <mvc:annotation-driven /> <bean name="greetingServiceImpl" class="com.demo.GreetingServiceImpl" /> <bean name="helloController" class="com.demo.HelloController"> <property name="greetingService" ref="greetingServiceImpl" /> </bean> </beans> <beans>— containing beans<bean>— construct a bean of a given class- sub-elements — constructor arguments and properties
<mvc:annotation-driven>— enable MVC related post processors to facilitate mapping requests to controller methods to support@RequestMappingetc.- URL patterns are relative to the
DispatcherServlet’s URL pattern
- URL patterns are relative to the
<context:annotation-config/>or<context:component-scan/>— see@Configuration
- example
# Beans
org.springframework.beans.BeanUtils— for instantiating beans, checking bean property types, copying bean properties, etc.static void copyProperties(Object source, Object target)
# Bean Attributes
# Bean Resolve Attributes
bean name — defaults to the defining class or method in camelCase
@org.springframework.beans.factory.annotation.Qualifier@Target(value={FIELD,METHOD,PARAMETER,TYPE,ANNOTATION_TYPE}) @Inherited public @interface QualifierString value()— defaults to class name in camelCase- use: categorization — constitute filtering criteria. For example, you can define multiple
MovieCatalogbeans with the same qualifier value “action”, all of which are injected into aSet<MovieCatalog>annotated with@Qualifier("action") - specify qualifier when autowiring — use with
@Autowired@Autowired public MailController(@Qualifier("smtp") MailSender mailSender) { this.mailSender = mailSender; } - in XML —
<bean qualifier=""> - in Java EE —
@javax.inject.Named
@org.springframework.context.annotation.Primary— a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency@Target(value={TYPE,METHOD}) public @interface Primary- in XML —
<bean primary>
- in XML —
@org.springframework.core.annotation.Order— the order after qualifier: determine the order of resolved elements in case of collection injection points (with several target beans matching by type and qualifier)@Target(value={TYPE,METHOD,FIELD}) public @interface Orderint value— defaults toOrdered.LOWEST_PRECEDENCE(Integer.MAX_VALUE)interface org.springframework.core.Ordered— implemented by objects that should be orderableint getOrder()org.springframework.core.PriorityOrdered— always applied before plainOrderedobjects- compared by
org.springframework.core.OrderComparator
# Bean On-Off Attributes
@org.springframework.context.annotation.Profile— a bean is eligible for registration when one or more specified profiles are active@Target(value={TYPE,METHOD}) @Conditional(value=org.springframework.context.annotation.ProfileCondition.class) public @interface Profile- set active profiles
ConfigurableEnvironment.setActiveProfiles- property
spring.profiles.active— asList<String>, for examplebook,dev- property
spring.profiles.default— fallback
- property
@ActiveProfiles— for test
String[] value— used inProfiles::ofto create a predicate, any style,!,&,|supported in profile expressions- in XML —
<bean profile="">, or in<beans>
- set active profiles
conditions — a component is only eligible for registration when all specified conditions match
@org.springframework.context.annotation.Conditional@Target(value={TYPE,METHOD}) public @interface ConditionalClass<? extends Condition>[] valueorg.springframework.context.annotation.Condition@FunctionalInterface public interface Conditionboolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)- see also sub-interface
ConfigurationCondition
org.springframework.boot.autoconfigure.condition—@ConditionalOnClass,@ConditionalOnPropertyand@ConditionalOnMissingBeanand more@ConditionalOnProperty(name="spring.mail.host", havingValue="foo", matchIfMissing=true)
# Bean Loading Attributes
@org.springframework.context.annotation.DependsOn— initialization-time dependency, and, in the case of singleton beans only, a corresponding destruction-time dependency@Target(value={TYPE,METHOD}) public @interface DependsOnString[] value- in XML —
<bean depends-on="">
@org.springframework.context.annotation.Lazy— a bean is to be lazily initialized@Target(value={TYPE,METHOD,CONSTRUCTOR,PARAMETER,FIELD}) public @interface Lazy- use on definitions — specify component initialization
- use when autowiring — leads to the creation of a lazy-resolution proxy for all affected dependencies, as an alternative to using
ObjectFactoryorProvider org.springframework.beans.factory.ObjectFactory—T getObject()@FunctionalInterface public interface ObjectFactory<T>org.springframework.beans.factory.ObjectProviderpublic interface ObjectProvider<T> extends ObjectFactory<T>, Iterable<T>
@org.springframework.context.annotation.Scope— the lifecycle of an instance@Target(value={TYPE,METHOD}) public @interface ScopeString value(),String scopeName()ConfigurableBeanFactory.SCOPE_SINGLETON—"singleton", defaultConfigurableBeanFactory.SCOPE_PROTOTYPE—"prototype", one instance of the bean is created every time the bean is injected into or retrieved from application contextWebApplicationContext.SCOPE_SESSION—"session", one instance of the bean is created for each session,proxyModerequired- shortcut —
@org.springframework.web.context.annotation.SessionScope - implementation —
org.springframework.web.context.request.SessionScope
- shortcut —
WebApplicationContext.SCOPE_REQUEST—"request", one instance of the bean is created for each request,proxyModerequired- shortcut —
@org.springframework.web.context.annotation.RequestScope - implementation —
org.springframework.web.context.request.RequestScope
- shortcut —
WebApplicationContext.SCOPE_APPLICATION—"application", one instance for oneServletContext(ApplicationContextfor"singleton")- shortcut —
@org.springframework.web.context.annotation.ApplicationScope
- shortcut —
CustomScopeConfigurer-- class for configuring custom scope
ScopedProxyMode proxyMode()—default ScopedProxyMode.DEFAULT, inject proxy as dependency, and instantiate the target bean when request or session incomingenum ScopedProxyModeDEFAULT,NOINTERFACES— preferred, create a JDK dynamic proxy implementing all interfaces exposed by the class of the target object, no proxy created if the target does not implement any interfaceTARGET_CLASS— create a class-based proxy (uses CGLIB)
# Bean Definitions
@org.springframework.context.annotation.Bean— indicates that a method produces a bean@Target(value={METHOD,ANNOTATION_TYPE}) public @interface BeanString[] value,String[] name— defaults to the method name- dependencies — an arbitrary number of parameters that describe the dependencies
boolean autowireCandidateString destroyMethodString initMethod- in XML —
<bean> - mode when declared within
@Configuration- inter-bean references — bean methods may reference other
@Beanmethods in the same class by calling them directly. This ensures that references between beans are strongly typed and navigable, guaranteed to respect scoping and AOP semantics - inter-bean references requirement — CGLIB subclassing of each such configuration class at runtime, thus no
finalorprivatefor bean factory methods
- inter-bean references — bean methods may reference other
- lite mode — when not annotated within
@Configuration, but@Componentor whatever- in XML —
<factory-method> - 'inter-bean references' are not supported — when one
@Bean-method invokes another@Bean-method in lite mode, the invocation is a standard Java method invocation; Spring does not intercept the invocation via a CGLIB proxy
- in XML —
- static
@Beanmethods forBeanFactoryPostProcessor— should be declared as a static method to be instantiated early in the container lifecycle, scoping and AOP semantics as trade off
@org.springframework.context.annotation.Configuration— indicates that a class declares one or more@Beanmethods, and/or property sources, feature switches@Target(value=TYPE) @Component public @interface ConfigurationString value—@AliasFor(annotation=Component.class)boolean proxyBeanMethods— see modes in@Bean- bootstrapping
AnnotationConfigApplicationContext::register, see Configure Contexts- use
<context:component-scan/>, which has anannotation-configattribute<context:annotation-config/>— enableorg.springframework.context.annotation.ConfigurationClassPostProcessorand other annotation-related post processors for bootstrapping processing of@Configurationclasses<beans> <context:annotation-config/> <bean class="com.acme.AppConfig"/> </beans>
- compose configurations —
@org.springframework.context.annotation.Import,@ImportResource(for XLM),<import>, or static inner@Configurationclasses @org.springframework.context.annotation.PropertySource— a convenient and declarative mechanism for adding aPropertySourceto Spring'sEnvironment, used in conjunction with@Configurationclasses@Target(value=TYPE) @Repeatable(value=PropertySources.class) public @interface PropertySource- in conjunction with
@Enable-—@EnableAsync,@EnableScheduling,@EnableTransactionManagement,@EnableAspectJAutoProxy,@EnableCaching,@EnableLoadTimeWeaving,@EnableWebMvc,@EnableMBeanExport,@EnableSpringConfigured,@EnableTransactionManagement - in conjunction with
@org.springframework.context.annotation.ComponentScan— configures component scanning directives, default annotation config processors assumed and noannotation-configattribute like<context:component-scan>@Target(value=TYPE) @Repeatable(value=ComponentScans.class) public @interface ComponentScanString[] value,String[] basePackages— defaults to declaring package, sub-packages also scanned- filters — defaults to include
@Component - more
- ensure singleton scope if scope is singleton —
@Configurationclasses are subclassed at startup-time with CGLIB. In the subclass, the child method checks the container first for any cached (scoped) beans before it calls the parent method and creates a new instance
@org.springframework.stereotype.Component— annotated classes are considered as candidates for auto-detection when using annotation-based configuration and classpath scanning@Target(value=TYPE) @Indexed public @interface ComponentString valuebean name, defaults to class name in camelCase- in Java EE —
@javax.inject.Named, but with a few subtle differences - special kind components,
@Componentmeta annotated@org.aspectj.lang.annotation.Aspect— component but not meta annotated by@Component@Controller@RestController—@Controllerwith@ResponseBody
@org.springframework.stereotype.Service— "an operation offered as an interface that stands alone in the model, with no encapsulated state."@org.springframework.stereotype.Repository— "a mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects", also for DAO
# Bean Lifecycle
org.springframework.context.Lifecycle— tbdSmartLifecycle
bean lifecycle — see javadoc of
BeanFactory- before ready to use
- instantiate
- populate properties
BeanNameAware’ssetBeanName()BeanFactoryAware’ssetBeanFactory()ApplicationContextAware’ssetApplicationContext()- Pre-initialization
BeanPostProcessors,postProcessBeforeInitialization() InitializingBean’safterPropertiesSet()- Call custom init-method
- Post-initialization
BeanPostProcessors,postProcessAfterInitialization()
- after container shutdown
DisposableBean’sdestroy()- Call custom destroy-method
- before ready to use
lifecycle hooks
- lifecycle, in
org.springframework.beans.factoryFactoryBean<T>— interface to be implemented by objects used within aBeanFactorywhich are themselves factories for individual objectsInitializingBean— interface to be implemented by beans that need to react once all their properties have beenDisposableBean— interface to be implemented by beans that want to release resources on destruction
org.springframework.beans.factory.Aware— a marker super interface for*Awareindicating that a bean is eligible to be notified by the Spring container of a particular framework object through a callback-style method- processing — processing done in a
BeanPostProcessor:ApplicationContextAwareProcessor org.springframework.beans.factoryBeanFactoryAware— interface to be implemented by beans that wish to be aware of their owningBeanFactoryBeanNameAware— interface to be implemented by beans that want to be aware of their bean name in a bean factory
org.springframework.contextEnvironmentAware—setEnvironment(Environment environment)ApplicationContextAware—setApplicationContext(ApplicationContext applicationContext)
ApplicationEventPublisherAwareMessageSourceAwareServletContextAware,ServletConfigAware
- processing — processing done in a
- lifecycle, in
# Dependency Injection
DI
- inject beans into application context
- inject initialized beans into dependencies on them
- injection preference — constructor > field > setter
@org.springframework.beans.factory.annotation.Autowired— marks a constructor, field, setter method, or config method as to be autowired, public or not@Target(value={CONSTRUCTOR,METHOD,PARAMETER,FIELD,ANNOTATION_TYPE}) public @interface Autowiredboolean required— defaults totrue, unwired when no matching- override for individual parameters —
Optional,@Nullable
- override for individual parameters —
- single constructor and multiple constructors
- implicitly if single constructor — if a class only declares a single constructor, it is always used and autowired
- inject as many dependencies as possible if multiple constructors annotated — if multiple non-required constructors declare the annotation, the one with the greatest number of dependencies that can be satisfied by matching beans in the Spring container will be chosen
- fallback — use the primary/default constructor
- other autowire target
- autowired parameters — supported by the JUnit Jupiter in the
spring-testmodule - Arrays, Collections, and Maps — if no bean itself is of match Collections or Map types, the container autowires all beans matching the declared value type, taking into account Ordered and
@Ordervalues
- autowired parameters — supported by the JUnit Jupiter in the
- injection is performed through a
AutowiredAnnotationBeanPostProcessor— cannot use@Autowiredto inject references intoBeanPostProcessororBeanFactoryPostProcessor - order when injecting — Matches by Type - Restricts by Qualifiers - Matches by Name
- in Java EE —
@javax.inject.Inject, but without required-vs-optional semantics;@javax.annotation.Resource, but with subtle differences
# Externalized Configuration
externalized values
- syntax — see SpEL
- Appendix A. Common application properties (opens new window)
- relaxed binding — name bindings take following forms
message.destinationNamemessage.destination-nameMESSAGE_DESTINATION_NAME
- add property files — use
@PropertySourceto inject property files intoEnvironment - resolving
${...}placeholders in<bean>and@Value,@PropertySourceannotations — must ensure that an appropriate embedded value resolver bean is registered- use
<context:property-placeholder>in XML - use a static
@Beanmethod returningPropertySourcesPlaceholderConfigurer
- use
- injection
@org.springframework.beans.factory.annotation.Value@Target(value={FIELD,METHOD,PARAMETER,ANNOTATION_TYPE}) public @interface Value@Autowired Environment env;- implement
org.springframework.context.EnvironmentAware @org.springframework.boot.context.properties.ConfigurationProperties— bind and validate some external Properties with common prefix@Target(value={TYPE,METHOD}) public @interface ConfigurationProperties- dependency for code completion —
org.springframework.boot:spring-boot-configuration-processor - example
@Component @ConfigurationProperties(prefix="myapp") public static class MyAppProperties { private String name; public String getName() { return name; } public void setName(String name) { // myapp.name this.name = name; } }
- dependency for code completion —
property related classes
org.springframework.core.env.PropertySources— holder containing one or morePropertySourceobjectspublic interface PropertySources extends Iterable<PropertySource<?>>org.springframework.core.env.PropertySource<T>— name/value property pairs from a source (T), which can beMap,ServletContextetc.
interface org.springframework.core.env.PropertyResolver— for resolving properties against any underlying sourcegetPropertymethodsorg.springframework.core.env.PropertySourcesPropertyResolver— resolves property values against an underlying set ofPropertySourcesorg.springframework.core.env.Environmentpublic interface Environment extends PropertyResolver
PropertySourceresolve order — 4.2. Externalized Configuration (opens new window) — former ones override later ones- devtools global settings properties in the
$HOME/.config/spring-bootdirectory when devtools is active - test related
- command line arguments — see arguments passing before
./mvnw spring-boot:run -Dserver.ip=192.168.12.1 # or after `./mvnw package` java -jar target/myapp.jar --data.server=remoteserver:3030 SPRING_APPLICATION_JSONenvironment variable —spring.application.jsoninapplication.propertiesSPRING_APPLICATION_JSON='{ "data":{"server":"remoteserver:3030"}}' java -Dspring.application.json='{"acme":{"name":"test"}}' -jar myapp.jar java -jar myapp.jar --spring.application.json='{"acme":{"name":"test"}}'- servlet
ServletConfiginit parametersServletContextinit parameters
- JNDI attributes from
java:comp/env - system properties
- OS Environment variables
- a
RandomValuePropertySourcethat has properties only inrandom.* - application properties
- outside the package jar
- profile-specific application properties (
application-{profile}.propertiesand YAML variants) - plain
application.propertiesand YAML variants
- profile-specific application properties (
- inside the package jar
- profile-specific application properties
- plain application properties
- outside the package jar
@PropertySourceSpringApplication::setDefaultProperties
- devtools global settings properties in the
profile files —
application-{profile}.propertiesand YAML variants- customize
spring.config.name— defaults toapplication, for customized config filenamespring.config.location— for customized locationspring.config.additional-locationspring.config.import
- set activate profiles
@org.springframework.test.context.ActiveProfilesConfigurableEnvironment::setActiveProfilesspring.profiles.active, usespring.profiles.defaultif not specified — defaults toapplication-default.properties;application.propertiesalways usedspring.profiles—List<String>that at least one should match for the document to be included, kind similar to the@Conditional- use new and less confusing
spring.config.activate.on-cloud-platform,spring.config.activate.on-profile(cannot be used withspring.profiles.active)
- use new and less confusing
spring.profiles.include—List<String>to unconditionally activate
- customize
# SpEL
SpEL basics
#{}— can be nested${}forEnvironmentvariables${...}placeholder default value syntax —${...:val}
- literals — int, float, String (single or double quote), boolean
- bean reference — can refer to other beans with bean name, properties of beans, call methods
- get
Classor invoke static —T(),T(java.lang.Math).PI - optional chaining —
#{artistSelector.selectArtist()?.toUpperCase()} - refer to system properties —
#{systemProperties['disc.title']}
operators
- arithmetic and relation operators — also be specified as a purely alphabetic equivalent, for compatibility in XML
instanceofmatches— regular expression based,'5.0067' matches '^-?\\d+(\\.\\d{2})?$'- logical —
and,or,not(!),| - conditional —
?:(ternary),?:(Elvis operator, null coalescing,??in JS) - collection —
[]accessor, also for String.?[expression]— filter according to expression#{jukebox.songs.?[artist eq 'Aerosmith']},artistis equivalent to#this.artist
.^[expression]— first match.^[expression]— last match.![property]— properties projection#{jukebox.songs.![title]}
Java interface
- package —
org.springframework.expressionand sub-packages - example
ExpressionParser parser = new SpelExpressionParser(); Expression exp = parser.parseExpression("'Hello World'.concat('!')"); String message = (String) exp.getValue();
- package —
# Aspects
AOP — addresses cross-cutting concerns
- aspect
@Aspect— the merger of advice and pointcuts - advice — the job of an aspect, what and when
@Before— The advice functionality takes place before the advised method is invoked.@After— The advice functionality takes place after the advised method completes, regardless of the outcome.@AfterReturning— The advice functionality takes place after the advised method successfully completes.@AfterThrowing— The advice functionality takes place after the advised method throws an exception.@Around— The advice wraps the advised method, providing some functionality before and after the advised method is invoked.- take
ProceedingJoinPointas a parameter toproceed()
- take
- join points — all the points within the execution flow of the application that are candidates to have advice applied
- pointcuts
@Pointcut— where, one or more join points at which advice should be woven - introduction — allows you to add new methods or attributes to existing classes
- weaving — the process of applying aspects to a target object to create a new proxied object
- Compile time — Aspects are woven in when the target class is compiled. This requires a special compiler. AspectJ’s weaving compiler weaves aspects this way.
- Class load time — Aspects are woven in when the target class is loaded into the JVM . This requires a special ClassLoader that enhances the target class’s byte- code before the class is introduced into the application. AspectJ 5’s load-time weaving ( LTW ) support weaves aspects this way.
- Runtime — Aspects are woven in sometime during the execution of the application. Typically, an AOP container dynamically generates a proxy object that delegates to the target object while weaving in the aspects. This is how Spring AOP aspects are woven.
- aspect
aspects in Spring
- woven into beans — wrapping with a proxy class
- if using an
ApplicationContext, the proxied objects will be created when it loads all the beans from theBeanFactory - Spring only supports method join points
- package —
org.aspectj.lang.annotation - enable AspectJ —
aspectjweaver.jar(org.aspectj:aspectjweaver) library is on the classpath and@EnableAspectJAutoProxy@Target(value=TYPE) @Import(value=org.springframework.context.annotation.AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy- auto-proxying — uses the
@Aspectannotated bean to create a proxy around any other beans for which the aspect’s pointcuts are a match
- auto-proxying — uses the
@EnableLoadTimeWeaving— tbd
pointcut expression Language
args()— Limits join-point matches to the execution of methods whose arguments are instances of the given types@args()— Limits join-point matches to the execution of methods whose arguments are annotated with the given annotation typesexecution()— Matches join points that are method executionsexecution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)execution(* concert.Performance.perform(..))— matchesconcert.Performance.performmethod with any return type (*) and any arguments (..)
this()— Limits join-point matches to those where the bean reference of the AOP proxy is of a given typetarget()— Limits join-point matches to those where the target object is of a given type@target()— Limits matching to join points where the class of the executing object has an annotation of the given typewithin()— Limits matching to join points within certain typeswithin(concert.*)— When the method is called from within any class in theconcertpackage
@within()— Limits matching to join points within types that have the given annotation (the execution of methods declared in types with the given annotation when using Spring AOP)@annotation— Limits join-point matches to those where the subject of the join point has the given annotationbean()— limits the pointcut’s effect to that specific beanbean('woodstock')
- logical —
||,&&,! +— any subtypes*,..,*Name(wildcard)
binding form — use a parameter name in place of a type name in an args expression, the value of the corresponding argument is passed as the parameter value when the advice is invoked
@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)") public void validateAccount(Account account) { // ... }- supports —
arg, the proxy object (this), target object (target), and annotations (@within,@target,@annotation, and@args)
- supports —
example using AOP
@Aspect public class Audience { @Pointcut("execution(* concert.Performance.perform(..))") public void performance() {} @Before("performance()") public void silenceCellPhones() { System.out.println("Silencing cell phones"); } @Before("execution(* com.xyz.myapp.dao.*.*(..))") public void doAccessCheck() { // ... } @Around("performance()") public void watchPerformance(ProceedingJoinPoint jp) { try { System.out.println("Silencing cell phones"); System.out.println("Taking seats"); jp.proceed(); System.out.println("CLAP CLAP CLAP!!!"); } catch (Throwable e) { System.out.println("Demanding a refund"); } } }aspect introduction — add new functionality (methods)
- add interface with default implementation — enable an aspect to declare that advised objects implement a given interface, and to provide an implementation of that interface on behalf of those objects
- example — all implementors of service interfaces also implement the
UsageTrackedinterface, the implementation isDefaultUsageTracked@Aspect public class UsageTracking { @DeclareParents(value="com.xzy.myapp.service.*+", defaultImpl=DefaultUsageTracked.class) public static UsageTracked mixin; @Before("com.xyz.myapp.SystemArchitecture.businessService() && this(usageTracked)") public void recordUsage(UsageTracked usageTracked) { usageTracked.incrementUseCount(); } }
# SpringMVC
# Enable MVC
@org.springframework.web.servlet.config.annotation.EnableWebMvc— imports the Spring MVC configuration fromWebMvcConfigurationSupportorg.springframework.web.servlet.config.annotation.WebMvcConfigurer— callback methods to customize the Java-based configuration for Spring MVC enabled via@EnableWebMvcdefault void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers)default void addCorsMappings(CorsRegistry registry)default void addFormatters(FormatterRegistry registry)default void addInterceptors(InterceptorRegistry registry)default void addResourceHandlers(ResourceHandlerRegistry registry)default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers)default void addViewControllers(ViewControllerRegistry registry)default void configureAsyncSupport(AsyncSupportConfigurer configurer)default void configureContentNegotiation(ContentNegotiationConfigurer configurer)default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers)default void configureMessageConverters(List<HttpMessageConverter<?>> converters)default void configurePathMatch(PathMatchConfigurer configurer)default void configureViewResolvers(ViewResolverRegistry registry)default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers)default void extendMessageConverters(List<HttpMessageConverter<?>> converters)default MessageCodesResolver getMessageCodesResolver()default Validator getValidator()
# DispatcherServlet
org.springframework.web.servlet.DispatcherServletpublic class DispatcherServlet extends FrameworkServletorg.springframework.web.servlet.FrameworkServletpublic abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAwareorg.springframework.web.servlet.HttpServletBeanpublic abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware
- creation
DispatcherServlet(WebApplicationContext webApplicationContext)DispatcherServlet()— create own web application context based on defaults and servlet init-params
dispatch targets — tbd
HandlerMappingHandlerAdapterHandlerExceptionResolverViewResolverLocaleResolverThemeResolverMultipartResolverFlashMapManager- defaults — tbd
- processing — tbd
org.springframework.web.servlet.support.RequestContextUtils— lookup of currentWebApplicationContext,LocaleResolver,Locale,ThemeResolver,Theme, andMultipartResolveretc. which has been set by theDispatcherServletbootstrap web application contexts
- example — see docs of
WebApplicationInitializerand SpringMVC org.springframework.web.context.ContextLoaderListener— bootstrap listener to start up and shut down Spring's rootWebApplicationContext. Simply delegates toContextLoaderas well as toContextCleanupListener.public class ContextLoaderListener extends ContextLoader implements ServletContextListener- initializers — extending
AbstractAnnotationConfigDispatcherServletInitializerfor hierarchy web application contextsorg.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer— with abstract methods specifying bean classes for root and non-root application contextsprotected abstract Class<?>[] getRootConfigClasses()— delegated bycreateRootApplicationContext()protected abstract Class<?>[] getServletConfigClasses()— delegated bycreateServletApplicationContext()- parents
interface org.springframework.web.WebApplicationInitializer—void onStartup(ServletContext servletContext)to configure theServletContextprogrammaticallyorg.springframework.web.context.AbstractContextLoaderInitializer— register aContextLoaderListenerwhenonStartup, only abstract methodcreateRootApplicationContext()org.springframework.web.servlet.support.AbstractDispatcherServletInitializer— with abstract methods for HTTP servlet configs like filters, mappings, etc.
org.springframework.web.SpringServletContainerInitializer— see Servlet
<init-param>s ofDispatcherServletcontextClass, defaults toXmlWebApplicationContextcontextConfigLocationnamespace— defaults to[servlet-name]-servletthrowExceptionIfNoHandlerFound— whether to throw aNoHandlerFoundExceptionwhen no handler was found for a request, which can then be caught with aHandlerExceptionResolver; defaults tofalse, return 404 and noException
- filter
org.springframework.boot.web.servlet.FilterRegistrationBean— aServletContextInitializerto register Filtersvoid setOrder(int order)
@org.springframework.boot.web.servlet.ServletComponentScan— Enables scanning for Servlet components (filters, servlets, and listeners annotations injavax.servlet.annotation). Scanning is only performed when using an embedded web server.
- example — see docs of
# Controller
@Controller,@RestController— controller, work in coordination with@RequestMappingorg.springframework.stereotype.Controller@Target(value=TYPE) @Component public @interface Controller@org.springframework.web.bind.annotation.RestController—@Controllerwith@ResponseBody, which means@RequestMappingmethods assume@ResponseBodysemantics by default@Target(value=TYPE) @Controller @ResponseBody public @interface RestController@org.springframework.web.bind.annotation.ResponseBody— indicates a method or methods of a class return value that should be bound to the web response body, instead of view resolution or rendering with an HTML template@Target(value={TYPE,METHOD}) public @interface ResponseBody@Inherited— this annotation is not annotated with@Inheritedbut is inherited
- AOP proxying — use class-based proxying or controller interface
- controller interface — make sure to put all mapping annotations on the controller interface rather than on the implementation class
@org.springframework.web.bind.annotation.RequestMapping@Target(value={TYPE,METHOD}) public @interface RequestMapping- method level inherit from type level — type level checked before method level
String[] path,String[] value- patterns —
?,*,**,{name},{name:regex}, SpEL property placeholders; use@PathVariableto capturedname - matcher implementation —
AntPathMatcher, can be customized - multiple match — when multiple patterns match a URL, the most specific one will be used, compared by
AntPathMatcher::getPatternComparator
- patterns —
String[] params—"myParam=myValue","myParam!=myValue","myParam","!myParam"String[] headers—"My-Header=myValue","My-Header!=myValue","!My-Header","content-type=text/*"String[] consumes—"text/plain",{"text/plain", "application/*"},MediaType.TEXT_PLAIN_VALUEString[] produces— like the above, but also parameters like"text/plain;charset=UTF-8"
RequestMethod[] method@GetMapping@PostMapping@PutMapping@DeleteMapping@PatchMapping
handler method parameters — docs (opens new window)
HandlerMethodArgumentResolver- standard servlet type parameters
HttpServletRequest,InputStreamorReaderHttpServletResponse,OutputStreamorWriterHttpSession,Localeorg.springframework.web.context.request.WebRequest—HttpServletRequest,HttpServletResponse,HttpSessionin one
org.springframework.web.bind.annotation- common properties
String name,String value— defaults to parameter name, but code is required to be compiled with debugging information or with the-parameterscompiler flag- automatic type conversion — automatically converted to the appropriate type, or
TypeMismatchException; useDataBinderto register custom type support, tbd - kv map — if the method parameter is
Map<String, String>,MultiValueMap<String, String>then the map is populated with all path variable names and values
- automatic type conversion — automatically converted to the appropriate type, or
boolean required—Exception, ornull/OptionalString defaultValue— defaults toValueConstants.DEFAULT_NONEto serve as nil
@PathVariable— captured URI template variable; nodefaultValue@RequestParam— query parameters, also form data, and parts in multipart when SpringMVC@RequestHeader@RequestPart— for multipart, tbd@MatrixVariable— RFC 3986 URI path parameters, parameters but in path segments, removed from the URL prior to matching it to a Servlet mappinghttp://www.example.com/hotel/43;floor=8;room=15/guest /hotel/43/guestString pathVar— for disambiguation when the same parameter persistent in different path segments;43in above case
- common properties
- POJO
@ModelAttribute— for access to an existing attribute in the model- plain POJO, called form object, aka. command object — if
BeanUtils::isSimpleProperty,@RequestParambut use a POJO,set-methods examined; otherwise@ModelAttribute @RequestBody— a method parameter should be bound to the body of the web request, converted byHttpMessageConverter- validate
@RequestMapping(value="join", method=RequestMethod.POST) public String join(@Valid UserRegistrationForm form, BindingResult validation)BindingResult— can beErrors, or omit and throwMethodArgumentNotValidExceptionwhen validation failed
HttpEntity<T>,RequestEntity<T>— header and body@org.springframework.security.core.annotation.AuthenticationPrincipal— resolveAuthentication.getPrincipal()to a method argument, usually of typeUserDetails- more
@ResponseStatushandler method return
void- model and view
- model —
Map<String, Object>,ModelMap,Model View,StringUrlBasedViewResolverforStringreturn type special view namesredirect:—RedirectViewforward:—InternalResourceView
ModelAndView
- model —
HttpEntity<T>,ResponseEntity<T>- POJO
@ResponseBody- plain POJO — as
@ModelAttribute
- async
DeferredResult<V>Callable<V>
error handling
@org.springframework.web.bind.annotation.ExceptionHandler— handling exceptions in specific handler classes and/or handler methods@Target(value=METHOD)Class<? extends Throwable>[] value— Exceptions handled by the annotated method. If empty, will default to any exceptions listed in the method argument list.
@org.springframework.web.bind.annotation.ControllerAdvice— declare@ExceptionHandler,@InitBinder, or@ModelAttributemethods to be shared across multiple@Controllerclasses@Target(value=TYPE) @ComponentString[] basePackages,String[] value— the packages and sub-packages in which to select controllers to be advised- more
org.springframework.web.server.ResponseStatusException— for exceptions associated with specific HTTP response status codes
org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice— customizing the response after the execution of an@ResponseBodyor aResponseEntitycontroller method but before the body is written with anHttpMessageConverter
# Validation
validation
- Bean Validation (opens new window) —
javax.validationpackage and sub-packages - Spring Validation (opens new window)
- Bean Validation (opens new window) —
validate
- cause validation to be applied —
MethodArgumentNotValidExceptionand 400 if not passed, can be used on handler methods arguments@javax.validation.Valid@org.springframework.validation.annotation.Validated- self define such annotations —
@javax.validation.Constraint
- configuration —
WebMvcConfigurer::WebMvcConfigurerforValidator, which defaults toLocalValidatorFactoryBean org.springframework.validation.Validator
- cause validation to be applied —
# Interceptor
HandlerMapping— define a mapping between requests and handler objects, along with a list of interceptors for pre- and post-processingRequestMappingHandlerMapping— for@RequestMapping
org.springframework.web.servlet.HandlerInterceptor— add common preprocessing behavior without needing to modify each handler implementation- async version —
org.springframework.web.servlet.AsyncHandlerInterceptor - register —
WebMvcConfigurer::addInterceptors boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)— returntrueso the handler execution chain continuespostHandle— less useful with@ResponseBodyandResponseEntitymethods for which the response is written and committed within theHandlerAdapterand beforepostHandleafterCompletion
- async version —
# Web Client
org.springframework.web.client.RestTemplate— synchronous client to perform HTTP requests, exposing a simple, template method API over underlying HTTP client libraries such as the JDKHttpURLConnection, Apache HttpComponents, and othersexchangemethodexecutemethod- more
- can
@LoadBalance
org.springframework.web.reactive.function.client.WebClient— non-blocking, reactive client to perform HTTP requests, exposing a fluent, reactive API over underlying HTTP client libraries such as Reactor Netty
# Data
transaction
org.springframework.transaction.PlatformTransactionManager— bean to configure for implementation of this interface as transaction infrastructureorg.springframework.jdbc.datasource.DataSourceTransactionManager—PlatformTransactionManagerimplementation for a single JDBCDataSourcejava.sql.Connection-like not thread-safe — thread bound and transaction linked, likejavax.persistency.EntityManager
- configure
@org.springframework.transaction.annotation.EnableTransactionManagement—<tx:annotation-driven/>, enables Spring's annotation-driven transaction management capabilityAdviceMode mode—AdviceMode.PROXY,AdviceMode.ASPECTJboolean proxyTargetClass— CGLIB or JDK proxy,truewill affect all Spring-managed beans requiring proxying, for example@Async
org.springframework.transaction.annotation.TransactionManagementConfigurer
@org.springframework.transaction.annotation.Transactional@Target(value={TYPE,METHOD}) @Inherited public @interface TransactionalString transactionManager,String value— optional, the qualifier value (or the bean name) of a specificTransactionManagerString[] rollbackForClassName,Class<? extends Throwable>[] rollbackFor— which exception types must cause a transaction rollback, defaults toRuntimeExceptionandErrorIsolation isolationPropagation propagation— defaults toPropagation.REQUIRED, use current transaction or create anew if none exists;Propagation.NESTED, a single physical transaction with multiple savepointsboolean readOnly- more
exception translation — unite error code and exceptions that extended
SQLExceptionfrom JDBC vendors- translator — configure translator implementation beans
org.springframework.dao.support.PersistenceExceptionTranslatororg.springframework.dao.support.ChainedPersistenceExceptionTranslator
- translation target —
@Repositorymethods; catchDataAccessExceptionnot in from the repository itself but callers org.springframework.dao.DataAccessExceptionorg.springframework.dao.NonTransientDataAccessExceptionorg.springframework.dao.RecoverableDataAccessExceptionorg.springframework.dao.TransientDataAccessException- more
- translator — configure translator implementation beans
javax.sql.DataSource— factory for connections, configure as beans for data sourcesorg.springframework.jdbc.datasource.DriverManagerDataSource— property settersorg.springframework.jdbc.datasource.lookup.JndiDataSourceLookup
Spring Data
org.springframework.data.repository.Repository<T, ID>org.springframework.data.repository.CrudRepository<T, ID>org.springframework.data.repository.PagingAndSortingRepository<T,ID>
MyBatis
- DAO example
@Mapper public interface UserDao { @Select("SELECT * FROM user WHERE name = #{name}") User findUserByName(@Param("name") String name); @Select("SELECT * FROM user") List<User> findAllUser(); @Insert("INSERT INTO user(name, age,money) VALUES(#{name}, #{age}, #{money})") void insertUser(@Param("name") String name, @Param("age") Integer age, @Param("money") Double money); @Update("UPDATE user SET name = #{name},age = #{age},money= #{money} WHERE id = #{id}") void updateUser(@Param("name") String name, @Param("age") Integer age, @Param("money") Double money, @Param("id") int id); @Delete("DELETE from user WHERE id = #{id}") void deleteUser(@Param("id") int id); } - multiple data source example
server.port=8335 # 配置第一个数据源 spring.datasource.hikari.db1.jdbc-url=jdbc:mysql://127.0.0.1:3306/erp?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8 spring.datasource.hikari.db1.username=root spring.datasource.hikari.db1.password=153963 spring.datasource.hikari.db1.driver-class-name=com.mysql.cj.jdbc.Driver@Configuration @MapperScan(basePackages = "top.snailclimb.db1.dao", sqlSessionTemplateRef = "db1SqlSessionTemplate") public class DataSource1Config { @Bean(name = "db1DataSource") @ConfigurationProperties(prefix = "spring.datasource.hikari.db1") @Primary public DataSource testDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "db1SqlSessionFactory") @Primary public SqlSessionFactory testSqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); // bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/db1/*.xml")); return bean.getObject(); } @Bean(name = "db1TransactionManager") @Primary public DataSourceTransactionManager testTransactionManager(@Qualifier("db1DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "db1SqlSessionTemplate") @Primary public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
- DAO example
# Jackson
com.fasterxml.jackson.annotationignore
@JsonIgnoreProperties@JsonIgnore
@JsonFormat@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone="GMT") private Date date;@JsonUnwrapped— flatten
# Integration
org.springframework.core.task.TaskExecutor@FunctionalInterface public interface TaskExecutor extends Executorvoid execute(Runnable task)
async
- configuration
@EnableAsync- executor —
TaskExecutorbean, or anExecutorbean named"taskExecutor",SimpleAsyncTaskExecutorif none found
- executor —
org.springframework.scheduling.annotation.AsyncConfigurer— for@Configuration,@EnableAsyncclassesdefault Executor getAsyncExecutor()default AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler()— uncaught exceptions are only logged by default
@org.springframework.scheduling.annotation.Async— the return type is constrained to eithervoidorFutureTaskExecutororg.springframework.core.task.AsyncTaskExecutor— with methods supportingFutureorg.springframework.core.task.SimpleAsyncTaskExecutor— fires up a new Thread for each task, useThreadPoolTaskExecutorfor thread poolsvoid setConcurrencyLimit(int concurrencyLimit)— defaults to unlimited
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutorsetCorePoolSizesetMaxPoolSizesetQueueCapacitysetRejectedExecutionHandler— defaults toThreadPoolExecutor.AbortPolicy
- configuration
scheduling
- scheduled
@org.springframework.scheduling.annotation.Scheduled— must expect no argumentsString cron— cron expressions, see javadoc ofCronSequenceGenerator
org.springframework.scheduling.TaskScheduler— the scheduling ofRunnables; the 'default' implementation isThreadPoolTaskSchedulerorg.springframework.scheduling.Trigger— can be used inTaskScheduler::scheduleorg.springframework.scheduling.support.CronTriggerorg.springframework.scheduling.support.PeriodicTrigger
TaskExecutor,org.springframework.scheduling.TaskSchedulerorg.springframework.scheduling.concurrent.ThreadPoolTaskScheduler—TaskSchedulerinterface wrapping a nativeScheduledThreadPoolExecutorvoid setPoolSize(int poolSize)— pool size defaults to 1
- configuration
@EnableSchedulingorg.springframework.scheduling.annotation.SchedulingConfigurerorg.springframework.scheduling.config.ScheduledTaskRegistrar—set-,add-,get-methodsvoid setTaskScheduler(TaskScheduler taskScheduler)
- scheduled
events
org.springframework.context.ApplicationEventorg.springframework.context.ApplicationListener<E extends ApplicationEvent>— only singleton beans@org.springframework.context.event.EventListenerorg.springframework.context.ApplicationEventPublisherorg.springframework.context.ApplicationEventPublisherAware
org.springframework.context.event.ApplicationEventMulticaster
method cache
- enable and config —
@org.springframework.cache.annotation.EnableCaching,org.springframework.cache.annotation.CachingConfigurer - interface
org.springframework.cache.Cache— common cache operations - interface
org.springframework.cache.CacheManager— cache manager SPI, allow for retrieving named Cache regions - implementations — JDK
java.util.concurrent.ConcurrentMapbased caches, Ehcache 2.x, Gemfire cache, Caffeine, and JSR-107 compliant caches (such as Ehcache 3.x) org.springframework.cache.annotation@Cacheable— Triggers cache population.@CacheEvict— Triggers cache eviction.@CachePut— Updates the cache without interfering with the method execution.@Caching— Regroups multiple cache operations to be applied on a method.@CacheConfig— Shares some common cache-related settings at class-level.
- enable and config —
# Security
security concepts
- authentication
Authorization: Digest- client certificates
- claims-based authentication — OAuth and SAML
- security related headers, configurable by
HttpSecurity::headersCache-Control: no-cache, no-store, max-age=0, must-revalidate,Pragma: no-cacheX-Content-Type-Options: nosniff— no MIME-sniffingStrict-Transport-Security: max-age=31536000; includeSubDomains— only use HTTPSX-Frame-OptionsX-XSS-Protection: 1; mode=block
- authentication
roles, activities, identities
org.springframework.security.core.context.SecurityContext— the minimum security information associated with the current thread of executionAuthentication getAuthentication()void setAuthentication(Authentication authentication)org.springframework.security.core.context.SecurityContextHolder— a series of static methods related toSecurityContextstatic SecurityContext getContext()
org.springframework.security.core.Authenticationpublic interface Authentication extends Principal, SerializableCollection<? extends GrantedAuthority> getAuthorities()Object getCredentials()Object getDetails()Object getPrincipal()boolean isAuthenticated()void setAuthenticated(boolean isAuthenticated)java.security.Principal— represent any entity, such as an individual, a corporation, and a login idorg.springframework.security.authentication.UsernamePasswordAuthenticationToken— anAuthenticationimplementation that is designed for simple presentation of a username and password
org.springframework.security.core.GrantedAuthority— an authority granted to anAuthenticationobjectorg.springframework.security.authentication.AuthenticationManager— processes anAuthenticationrequest, default implementationProviderManagerdelegates toAuthenticationProviderimplementationsAuthentication authenticate(Authentication authentication)org.springframework.security.authentication.AuthenticationProvider— can process a specificAuthenticationimplementationAuthentication authenticate(Authentication authentication)boolean supports(java.lang.Class<?> authentication)org.springframework.security.authentication.dao.DaoAuthenticationProvider— anAuthenticationProviderimplementation that retrieves user details from aUserDetailsService
org.springframework.security.core.userdetails.UserDetails— store user information, such as the username and password,GrantedAuthoritys, and whether the user is enabled, expired, and locked out; which is later encapsulated intoAuthenticationobjects, e.g. by authentication providersUserDetailsService::loadUserByUsername
org.springframework.security.core.AuthenticationException— authentication fail,RuntimeExceptionorg.springframework.security.access.AccessDeniedException— anAuthenticationobject does not hold a required authority
configure
org.springframework.web.filter.DelegatingFilterProxy— proxy for a standard Servlet Filter, delegating to a Spring-managed bean that implements theFilterinterfaceFilterChainProxy— register security filtersorg.springframework.security.web.SecurityFilterChain— used byFilterChainProxyto determine which Spring Security Filters should be invoked for this request
org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer— registers theDelegatingFilterProxyto use thespringSecurityFilterChainbefore any other registeredFilter@org.springframework.security.config.annotation.web.configuration.EnableWebSecurity— add this annotation to an@Configurationclass to have the Spring Security configuration defined in anyWebSecurityConfigureror more likely by extending theWebSecurityConfigurerAdapterbase class and overriding individual methodsorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter— a convenient base class for creating aWebSecurityConfigurerinstanceprotected void configure(AuthenticationManagerBuilder auth)— used by the default implementation ofauthenticationManager()to attempt to obtain anAuthenticationManagerAuthenticationManager authenticationManagerBean()— to be exposed as a@Bean
protected void configure(HttpSecurity http)void configure(WebSecurity web)
- example — see javadoc of
@EnableWebSecurity
builders in configurations
org.springframework.security.config.annotation.web.builders.HttpSecurity— configuring web based security for specific http requestspublic final class HttpSecurity extends AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain,HttpSecurity> implements SecurityBuilder<DefaultSecurityFilterChain>, HttpSecurityBuilder<HttpSecurity>org.springframework.security.config.annotation.web.builders.WebSecurity— to create theFilterChainProxyknown as the Spring Security Filter Chain (springSecurityFilterChain)public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,WebSecurity> implements SecurityBuilder<Filter>, ApplicationContextAwareorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder— used to create anAuthenticationManager. Allows for easily building in memory authentication, LDAP authentication, JDBC based authentication, addingUserDetailsService, and addingAuthenticationProviderspublic class AuthenticationManagerBuilder extends AbstractConfiguredSecurityBuilder<AuthenticationManager,AuthenticationManagerBuilder> implements ProviderManagerBuilder<AuthenticationManagerBuilder>JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder> jdbcAuthentication()InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuthentication()LdapAuthenticationProviderConfigurer<AuthenticationManagerBuilder> ldapAuthentication()<T extends UserDetailsService> DaoAuthenticationConfigurer<AuthenticationManagerBuilder,T> userDetailsService(T userDetailsService)
security events in
org.springframework.security.authentication.eventAbstractAuthenticationFailureEvent— subclasses indicate more detailed reasons for failureAuthenticationSuccessEvent— also remember-me authenticationInteractiveAuthenticationSuccessEvent
org.springframework.security.web.authentication.session.SessionFixationProtectionEventorg.springframework.security.core.session.SessionDestroyedEvent
method security
- imperative —
SecurityContextHolder @AuthenticationPrincipal— binds a method parameter or method return value to theAuthentication.getPrincipal()@org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurityboolean jsr250Enabledboolean securedEnabledboolean prePostEnabledorg.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration
jsr250Enabled:javax.annotation.securityannotations —@RolesAllowed-@PermitAll- moresecuredEnabled:@org.springframework.security.access.annotation.Secured— attributes, like"ROLE_USER","IS_AUTHENTICATED_REMEMBERED"prePostEnabled: inorg.springframework.security.access.prepost,pre-for parameters,post-for returns@PreAuthorize@PostAuthorize@PreFilter— filtering of collections and arrays@PostFilter
- URL —
HttpSecurity::authorizeRequestsprotected void configure(HttpSecurity http) throws Exception { http // ... .authorizeRequests(authorize -> authorize .mvcMatchers("/resources/**", "/signup", "/about").permitAll() .mvcMatchers("/admin/**").hasRole("ADMIN") .mvcMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") .anyRequest().denyAll() ); }org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry— matchers, order sensitiveanyRequestantMatchers—AntPathMatcherrequestMatchers—RequestMatcher, simple strategy to match anHttpServletRequestmvcMatchers—MvcRequestMatcher, e.g. for/securedas well as/secured/,/secured.html,/secured.xyzregexMatchers—RegexRequestMatcher
org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.AuthorizedUrlnot()permitAll()denyAll()- authorization requirement
authenticated()anonymous()
- attributes
access(String attribute)— SpELhasAuthority(String authority)—"ROLE_"not automatically inserted
hasAnyAuthority(String... authorities)hasRole(String role)—"ROLE_"automatically inserted
hasAnyRole(String... roles)hasIpAddress(String ipaddressExpression)
- remember
rememberMe()fullyAuthenticated()
- imperative —
authorization decisions behind scenes
org.springframework.security.access.AccessDecisionVoter- decisions —
static int,ACCESS_ABSTAIN,ACCESS_DENIED,ACCESS_GRANTED org.springframework.security.acls.AclEntryVoter— access control lists basedorg.springframework.security.access.vote.AuthenticatedVoter— for special-case rolesIS_AUTHENTICATED_ANONYMOUSLY,IS_AUTHENTICATED_REMEMBERED, andIS_AUTHENTICATED_FULLY- method security
org.springframework.security.access.annotation.Jsr250Voterorg.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter
- role
org.springframework.security.access.vote.RoleHierarchyVoterorg.springframework.security.access.vote.RoleVoter
org.springframework.security.web.access.expression.WebExpressionVoter—HttpSecurity
- decisions —
org.springframework.security.access.AccessDecisionManager— final decisionsorg.springframework.security.access.vote.AffirmativeBased, defaultorg.springframework.security.access.vote.ConsensusBasedorg.springframework.security.access.vote.UnanimousBased
access control list (or ACL) — tbd
OAuth 2 — tbd
- provider end point —
org.springframework.security.oauth2.provider.endpointAuthorizationEndpoint— for authorization. Default URL:/oauth/authorizeTokenEndpoint— for access tokens. Default URL:/oauth/token
- authorization server configuration
@EnableAuthorizationServerAuthorizationServerConfigurer
- resource server filter —
OAuth2AuthenticationProcessingFilter
- provider end point —
# Spring Boot
@org.springframework.boot.autoconfigure.SpringBootApplication— singleton with arunmethod which executes the application@Target(value=TYPE) @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters={@ComponentScan.Filter(type=CUSTOM,classes=TypeExcludeFilter.class),}) public @interface SpringBootApplication- equivalent —
@Configuration,@ComponentScan, and@EnableAutoConfigurationcombined Class<?>[] exclude—excludein@EnableAutoConfiguration
- equivalent —
@org.springframework.boot.autoconfigure.EnableAutoConfiguration— handle@Enable<Technology>@Target(value=TYPE) @Inherited @AutoConfigurationPackage @Import(value=AutoConfigurationImportSelector.class) public @interface EnableAutoConfigurationAutoConfigurationImportSelectoruses classpath to find all the necessary configuration classesAutoConfigurationImportSelector::getCandidateConfigurationslooks for theMETA-INF/spring.factoriesdefined in thespring-boot-autoconfigurejar, which defines all the auto-configuration classes needed
- Disabling Specific Auto-configuration Classes
@Configuration @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) // or excludeName with fully qualified name public class MyConfiguration { }- also
spring.autoconfigure.excludeproperty Class<?>[] excludeString[] excludeName
- also
SpringApplication— bootstrap and launch a Spring application from a Java main method, have control over the mainApplicationContext- run
static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args)
static ConfigurableApplicationContext run(Class<?> primarySource, String... args)ConfigurableApplicationContext run(String... args)
- builder style —
org.springframework.boot.builder.SpringApplicationBuilderpublic static void main(String[] args) { new SpringApplicationBuilder() .bannerMode(Banner.Mode.OFF) .sources(SpringBootSimpleApplication.class) .run(args); } - tbd
- run
ApplicationArguments—argsfromSpringApplication::runare accessible for beans@Component class MyComponent { private static final Logger log = LoggerFactory.getLogger(MyComponent.class); @Autowired public MyComponent(ApplicationArguments args) { boolean enable = args.containsOption("enable"); if(enable) log.info("## > You are enabled!"); List<String> _args = args.getNonOptionArgs(); log.info("## > extra args ..."); if(!_args.isEmpty()) _args.forEach(file -> log.info(file)); } }argsformat--option_name=valuenon_option_args1, non_option_args2
- pass
argsfrom CLI./mvnw spring-boot:run -Dspring-boot.run.arguments="--enable" - pass
argsfrom JAR./mvnw package java -jar spring-boot-simple-0.0.1-SNAPSHOT.jar --enable arg1 arg2
run code after
SpringApplication::run—ApplicationRunnerandCommandLineRunner@Bean CommandLineRunner myMethod() { return args -> { log.info("## > CommandLineRunner Implementation..."); log.info("Accessing the Info bean: " + info); for(String arg:args) log.info(arg); }; }
# JUnit 5
docs
maven config for integration with spring
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>junit</groupId> <artifactId>junit</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <scope>test</scope> </dependency>Spring JUnit Jupiter Testing Annotations (opens new window)
@SpringJUnitConfig— extends JUnit Jupiter with Spring test framework (@ExtendWith) and configuresApplicationContext(@ContextConfiguration)@ExtendWith(value=SpringExtension.class) @ContextConfiguration @Inherited @Target(value=TYPE) public @interface SpringJUnitConfigClass<?>[] value— Alias forContextConfiguration.classes(), classes to use for loading anApplicationContext
@SpringJUnitWebConfig@EnabledIf— signal that the annotated JUnit Jupiter test class or test method is enabled and should be run if the suppliedexpressionevaluates totrueexpressioncan be — SpEL,Environmentproperties, text literals
@DisabledIf@SpringBootTest— works by creating theApplicationContextused in your tests throughSpringApplication, an alternative to@SpringJUnitConfig@Target(value=TYPE) @Inherited @BootstrapWith(value=SpringBootTestContextBootstrapper.class) @ExtendWith(value=org.springframework.test.context.junit.jupiter.SpringExtension.class) public @interface SpringBootTest
other test related annotations in Spring
@BootstrapWith@ContextConfiguration@ContextHierarchy@ActiveProfiles@TestPropertySource@DirtiesContext@WebAppConfiguration@TestExecutionListeners@Transactional@BeforeTransaction@AfterTransaction@Commit@Rollback@Sql@SqlConfig@SqlGroup
JUnit Annotations (opens new window)
- define a test method
@Test— plain test method@RepeatedTest@ParameterizedTest@TestFactory
- test method name
@DisplayName@DisplayNameGeneration
- test instance lifecycle
@TestInstance— configure the test instance lifecycleTestInstance.Lifecycle.PER_CLASS— a new test instance will be created once per test classTestInstance.Lifecycle.PER_METHOD— default, a new test instance will be created for each test method or test factory method- condition when
PER_METHOD— the test class will still be instantiated if a given test method is disabled via a condition (e.g., @Disabled, @DisabledOnOs, etc.)
@BeforeAll— Denotes that the annotated method should be executed before all test methods@BeforeEach— the annotated method should be executed before each test method@AfterEach— Denotes that the annotated method should be executed after each test method@AfterAll— Denotes that the annotated method should be executed after all test methods
- define a test method
test console output
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); private final ByteArrayOutputStream errContent = new ByteArrayOutputStream(); private final PrintStream originalOut = System.out; private final PrintStream originalErr = System.err; @BeforeEach public void setUpStreams() { System.setOut(new PrintStream(outContent)); System.setErr(new PrintStream(errContent)); } @AfterEach public void restoreStreams() { System.setOut(originalOut); System.setErr(originalErr); }JUnit 4 example for comparaison
import static org.junit.Assert.*; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=CDPlayerConfig.class) public class CDPlayerTest { @Autowired private CompactDisc cd; @Test public void cdShouldNotBeNull() { assertNotNull(cd); } }