# 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
@Component
becomes 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 required
in annotation parameter —Exception
ornull
java.util.Optional
as method parameter — equivalent torequired
setfalse
- 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::value
annotated on the implementation,null
if not annotated with@HandlesTypes
orvalue
is empty
- SPI — implementations as service provider in
META-INF/services
inside JAR files org.springframework.web.SpringServletContainerInitializer
— Spring's implementation, defaults to delegating to allWebApplicationInitializer::onStartup
withservletContext
@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 GenericServlet
public 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 thedoXXX
methods
- HTTP methods,
throws ServletException, IOException
protected 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)
,ServletConfig
andServletContext
are already availablevoid destroy()
- get config
ServletConfig getServletConfig()
ServletContext getServletContext()
interface javax.servlet.ServletConfig
— configures inweb.xml
String getInitParameter(String name)
Enumeration<String> getInitParameterNames()
ServletContext getServletContext()
String getServletName()
- dispatch
config
HttpServlet
— inweb.xml
or by annotations@javax.servlet.annotation.WebServlet
@Target(value=TYPE) public @interface WebServlet
boolean 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
default
servlet, implementation isorg.apache.catalina.servlets.DefaultServlet
for 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
addFilter
addListener
addServlet
- context parameter
interface javax.servlet.AsyncContext
— initialized byServletRequest::startAsync
void start(Runnable run)
boolean hasOriginalRequestAndResponse()
# HTTP Servlet Request and Response
javax.servlet.http.HttpServletRequest
public 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()
orgetReader
will throwIllegalStateException
BufferedReader getReader()
,ServletInputStream getInputStream()
javax.servlet.ServletInputStream
— can haveReadListener
to notify when possible to read
- file upload, or the
multipart/form-data
MIME typePart getPart(String name)
,Collection<Part> getParts()
@javax.servlet.annotation.MultipartConfig
— annotated instances of theServlet
expect requests that conform to themultipart/form-data
MIME typeint fileSizeThreshold
-long maxFileSize
-long maxRequestSize
String 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.HttpServletRequestWrapper
for 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.HttpServletResponse
public interface HttpServletResponse extends ServletResponse
boolean isCommitted()
— a committed response has already had its status code and headers written- status code and redirect
static int
fields- status code setter and getter
sendError
— can optionally specify an error message
sendRedirect
- response body
ServletOutputStream getOutputStream()
,PrintWriter getWriter()
- buffer related methods
javax.servlet.ServletOutputStream
abstract 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.HttpServletResponseWrapper
for extending
# Servlet Listeners
config listeners
- in
web.xml
—<listener>
ServletContext::addListener
— called within a registeredServletContextListener::contextInitialized
orServletContainerInitializer::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.EventListener
javax.servlet.ServletContextListener
default void contextDestroyed(ServletContextEvent sce)
default void contextInitialized(ServletContextEvent sce)
javax.servlet.http.HttpSessionAttributeListener
javax.servlet.http.HttpSessionBindingListener
— no config required, event triggered when set or removed from aHttpSession
or 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 ofServletContextListener
sdefault 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::forward
ed andRequestDispatcher::include
ed requests — handled internally as a separate request- error requests
AsyncContext
dispatched requests
filter config
@javax.servlet.annotation.WebFilter
— cannot determine order; alternatively useServletContext::addListener
inServletContextListener::contextInitialized
orServletContainerInitializer::onStartup
and the order depends on the call@Target(value=TYPE) public @interface WebFilter
description
,displayName
,filterName
,smallIcon
,largeIcon
String[] servletNames
String[] urlPatterns
DispatcherType[] dispatcherTypes
—ASYNC
,ERROR
,FORWARD
,INCLUDE
,REQUEST
WebInitParam[] initParams
boolean 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 containergetBean
method — get a bean with type, name and/or other args as parameter(s)getBeanProvider
method — 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, ResourcePatternResolver
org.springframework.beans.factory.ListableBeanFactory
—BeanFactory
but return iterable objects containing beansorg.springframework.context.ApplicationEventPublisher
— the ability topublishEvent
to registered listenersorg.springframework.core.io.ResourceLoader
— the ability to load file or URL resources in a generic fashionorg.springframework.core.io.support.ResourcePatternResolver
— getResource
for 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
—ApplicationContext
but configurablepublic interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable
org.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.AnnotationConfigApplicationContext
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
org.springframework.context.support.AbstractRefreshableConfigApplicationContext
— base class for XML-based application context implementationsorg.springframework.context.support.ClassPathXmlApplicationContext
org.springframework.context.support.FileSystemXmlApplicationContext
org.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
@Configuration
for 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@RequestMapping
etc.- 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 Qualifier
String value()
— defaults to class name in camelCase- use: categorization — constitute filtering criteria. For example, you can define multiple
MovieCatalog
beans 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 Order
int 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 plainOrdered
objects- 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::of
to 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 Conditional
Class<? extends Condition>[] value
org.springframework.context.annotation.Condition
@FunctionalInterface public interface Condition
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)
- see also sub-interface
ConfigurationCondition
org.springframework.boot.autoconfigure.condition
—@ConditionalOnClass
,@ConditionalOnProperty
and@ConditionalOnMissingBean
and 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 DependsOn
String[] 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
ObjectFactory
orProvider
org.springframework.beans.factory.ObjectFactory
—T getObject()
@FunctionalInterface public interface ObjectFactory<T>
org.springframework.beans.factory.ObjectProvider
public interface ObjectProvider<T> extends ObjectFactory<T>, Iterable<T>
@org.springframework.context.annotation.Scope
— the lifecycle of an instance@Target(value={TYPE,METHOD}) public @interface Scope
String 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,proxyMode
required- 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,proxyMode
required- shortcut —
@org.springframework.web.context.annotation.RequestScope
- implementation —
org.springframework.web.context.request.RequestScope
- shortcut —
WebApplicationContext.SCOPE_APPLICATION
—"application"
, one instance for oneServletContext
(ApplicationContext
for"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 ScopedProxyMode
DEFAULT
,NO
INTERFACES
— 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 Bean
String[] value
,String[] name
— defaults to the method name- dependencies — an arbitrary number of parameters that describe the dependencies
boolean autowireCandidate
String destroyMethod
String initMethod
- in XML —
<bean>
- mode when declared within
@Configuration
- inter-bean references — bean methods may reference other
@Bean
methods 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
final
orprivate
for bean factory methods
- inter-bean references — bean methods may reference other
- lite mode — when not annotated within
@Configuration
, but@Component
or 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
@Bean
methods 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@Bean
methods, and/or property sources, feature switches@Target(value=TYPE) @Component public @interface Configuration
String value
—@AliasFor(annotation=Component.class)
boolean proxyBeanMethods
— see modes in@Bean
- bootstrapping
AnnotationConfigApplicationContext::register
, see Configure Contexts- use
<context:component-scan/>
, which has anannotation-config
attribute<context:annotation-config/>
— enableorg.springframework.context.annotation.ConfigurationClassPostProcessor
and other annotation-related post processors for bootstrapping processing of@Configuration
classes<beans> <context:annotation-config/> <bean class="com.acme.AppConfig"/> </beans>
- compose configurations —
@org.springframework.context.annotation.Import
,@ImportResource
(for XLM),<import>
, or static inner@Configuration
classes @org.springframework.context.annotation.PropertySource
— a convenient and declarative mechanism for adding aPropertySource
to Spring'sEnvironment
, used in conjunction with@Configuration
classes@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-config
attribute like<context:component-scan>
@Target(value=TYPE) @Repeatable(value=ComponentScans.class) public @interface ComponentScan
String[] value
,String[] basePackages
— defaults to declaring package, sub-packages also scanned- filters — defaults to include
@Component
- more
- ensure singleton scope if scope is singleton —
@Configuration
classes 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 Component
String value
bean name, defaults to class name in camelCase- in Java EE —
@javax.inject.Named
, but with a few subtle differences - special kind components,
@Component
meta annotated@org.aspectj.lang.annotation.Aspect
— component but not meta annotated by@Component
@Controller
@RestController
—@Controller
with@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
BeanPostProcessor
s,postProcessBeforeInitialization()
InitializingBean
’safterPropertiesSet()
- Call custom init-method
- Post-initialization
BeanPostProcessor
s,postProcessAfterInitialization()
- after container shutdown
DisposableBean
’sdestroy()
- Call custom destroy-method
- before ready to use
lifecycle hooks
- lifecycle, in
org.springframework.beans.factory
FactoryBean<T>
— interface to be implemented by objects used within aBeanFactory
which 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*Aware
indicating 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.factory
BeanFactoryAware
— interface to be implemented by beans that wish to be aware of their owningBeanFactory
BeanNameAware
— interface to be implemented by beans that want to be aware of their bean name in a bean factory
org.springframework.context
EnvironmentAware
—setEnvironment(Environment environment)
ApplicationContextAware
—setApplicationContext(ApplicationContext applicationContext)
ApplicationEventPublisherAware
MessageSourceAware
ServletContextAware
,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 Autowired
boolean 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-test
module - 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
@Order
values
- autowired parameters — supported by the JUnit Jupiter in the
- injection is performed through a
AutowiredAnnotationBeanPostProcessor
— cannot use@Autowired
to inject references intoBeanPostProcessor
orBeanFactoryPostProcessor
- 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.destinationName
message.destination-name
MESSAGE_DESTINATION_NAME
- add property files — use
@PropertySource
to inject property files intoEnvironment
- resolving
${...}
placeholders in<bean>
and@Value
,@PropertySource
annotations — must ensure that an appropriate embedded value resolver bean is registered- use
<context:property-placeholder>
in XML - use a static
@Bean
method 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 morePropertySource
objectspublic interface PropertySources extends Iterable<PropertySource<?>>
org.springframework.core.env.PropertySource<T>
— name/value property pairs from a source (T
), which can beMap
,ServletContext
etc.
interface org.springframework.core.env.PropertyResolver
— for resolving properties against any underlying sourcegetProperty
methodsorg.springframework.core.env.PropertySourcesPropertyResolver
— resolves property values against an underlying set ofPropertySources
org.springframework.core.env.Environment
public interface Environment extends PropertyResolver
PropertySource
resolve order — 4.2. Externalized Configuration (opens new window) — former ones override later ones- devtools global settings properties in the
$HOME/.config/spring-boot
directory 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_JSON
environment variable —spring.application.json
inapplication.properties
SPRING_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
ServletConfig
init parametersServletContext
init parameters
- JNDI attributes from
java:comp/env
- system properties
- OS Environment variables
- a
RandomValuePropertySource
that has properties only inrandom.*
- application properties
- outside the package jar
- profile-specific application properties (
application-{profile}.properties
and YAML variants) - plain
application.properties
and YAML variants
- profile-specific application properties (
- inside the package jar
- profile-specific application properties
- plain application properties
- outside the package jar
@PropertySource
SpringApplication::setDefaultProperties
- devtools global settings properties in the
profile files —
application-{profile}.properties
and YAML variants- customize
spring.config.name
— defaults toapplication
, for customized config filenamespring.config.location
— for customized locationspring.config.additional-location
spring.config.import
- set activate profiles
@org.springframework.test.context.ActiveProfiles
ConfigurableEnvironment::setActiveProfiles
spring.profiles.active
, usespring.profiles.default
if not specified — defaults toapplication-default.properties
;application.properties
always 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${}
forEnvironment
variables${...}
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
Class
or 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
instanceof
matches
— 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']}
,artist
is equivalent to#this.artist
.^[expression]
— first match.^[expression]
— last match.![property]
— properties projection#{jukebox.songs.![title]}
Java interface
- package —
org.springframework.expression
and 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
ProceedingJoinPoint
as 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
@Aspect
annotated 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.perform
method 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 theconcert
package
@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
UsageTracked
interface, 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 fromWebMvcConfigurationSupport
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
— callback methods to customize the Java-based configuration for Spring MVC enabled via@EnableWebMvc
default 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.DispatcherServlet
public class DispatcherServlet extends FrameworkServlet
org.springframework.web.servlet.FrameworkServlet
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware
org.springframework.web.servlet.HttpServletBean
public 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
HandlerMapping
HandlerAdapter
HandlerExceptionResolver
ViewResolver
LocaleResolver
ThemeResolver
MultipartResolver
FlashMapManager
- defaults — tbd
- processing — tbd
org.springframework.web.servlet.support.RequestContextUtils
— lookup of currentWebApplicationContext
,LocaleResolver
,Locale
,ThemeResolver
,Theme
, andMultipartResolver
etc. which has been set by theDispatcherServlet
bootstrap web application contexts
- example — see docs of
WebApplicationInitializer
and SpringMVC org.springframework.web.context.ContextLoaderListener
— bootstrap listener to start up and shut down Spring's rootWebApplicationContext
. Simply delegates toContextLoader
as well as toContextCleanupListener
.public class ContextLoaderListener extends ContextLoader implements ServletContextListener
- initializers — extending
AbstractAnnotationConfigDispatcherServletInitializer
for 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 theServletContext
programmaticallyorg.springframework.web.context.AbstractContextLoaderInitializer
— register aContextLoaderListener
whenonStartup
, 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 ofDispatcherServlet
contextClass
, defaults toXmlWebApplicationContext
contextConfigLocation
namespace
— defaults to[servlet-name]-servlet
throwExceptionIfNoHandlerFound
— whether to throw aNoHandlerFoundException
when 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
— aServletContextInitializer
to 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@RequestMapping
org.springframework.stereotype.Controller
@Target(value=TYPE) @Component public @interface Controller
@org.springframework.web.bind.annotation.RestController
—@Controller
with@ResponseBody
, which means@RequestMapping
methods assume@ResponseBody
semantics 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@Inherited
but 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@PathVariable
to 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_VALUE
String[] 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
,InputStream
orReader
HttpServletResponse
,OutputStream
orWriter
HttpSession
,Locale
org.springframework.web.context.request.WebRequest
—HttpServletRequest
,HttpServletResponse
,HttpSession
in 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-parameters
compiler flag- automatic type conversion — automatically converted to the appropriate type, or
TypeMismatchException
; useDataBinder
to 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
/Optional
String defaultValue
— defaults toValueConstants.DEFAULT_NONE
to 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/guest
String pathVar
— for disambiguation when the same parameter persistent in different path segments;43
in 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
,@RequestParam
but 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 throwMethodArgumentNotValidException
when 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
@ResponseStatus
handler method return
void
- model and view
- model —
Map<String, Object>
,ModelMap
,Model
View
,String
UrlBasedViewResolver
forString
return type special view namesredirect:
—RedirectView
forward:
—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@ModelAttribute
methods to be shared across multiple@Controller
classes@Target(value=TYPE) @Component
String[] 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@ResponseBody
or aResponseEntity
controller method but before the body is written with anHttpMessageConverter
# Validation
validation
- Bean Validation (opens new window) —
javax.validation
package and sub-packages - Spring Validation (opens new window)
- Bean Validation (opens new window) —
validate
- cause validation to be applied —
MethodArgumentNotValidException
and 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::WebMvcConfigurer
forValidator
, 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)
— returntrue
so the handler execution chain continuespostHandle
— less useful with@ResponseBody
andResponseEntity
methods for which the response is written and committed within theHandlerAdapter
and beforepostHandle
afterCompletion
- 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 othersexchange
methodexecute
method- 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
—PlatformTransactionManager
implementation for a single JDBCDataSource
java.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.ASPECTJ
boolean proxyTargetClass
— CGLIB or JDK proxy,true
will 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 Transactional
String transactionManager
,String value
— optional, the qualifier value (or the bean name) of a specificTransactionManager
String[] rollbackForClassName
,Class<? extends Throwable>[] rollbackFor
— which exception types must cause a transaction rollback, defaults toRuntimeException
andError
Isolation isolation
Propagation 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
SQLException
from JDBC vendors- translator — configure translator implementation beans
org.springframework.dao.support.PersistenceExceptionTranslator
org.springframework.dao.support.ChainedPersistenceExceptionTranslator
- translation target —
@Repository
methods; catchDataAccessException
not in from the repository itself but callers org.springframework.dao.DataAccessException
org.springframework.dao.NonTransientDataAccessException
org.springframework.dao.RecoverableDataAccessException
org.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.annotation
ignore
@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 Executor
void execute(Runnable task)
async
- configuration
@EnableAsync
- executor —
TaskExecutor
bean, or anExecutor
bean named"taskExecutor"
,SimpleAsyncTaskExecutor
if none found
- executor —
org.springframework.scheduling.annotation.AsyncConfigurer
— for@Configuration
,@EnableAsync
classesdefault Executor getAsyncExecutor()
default AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler()
— uncaught exceptions are only logged by default
@org.springframework.scheduling.annotation.Async
— the return type is constrained to eithervoid
orFuture
TaskExecutor
org.springframework.core.task.AsyncTaskExecutor
— with methods supportingFuture
org.springframework.core.task.SimpleAsyncTaskExecutor
— fires up a new Thread for each task, useThreadPoolTaskExecutor
for thread poolsvoid setConcurrencyLimit(int concurrencyLimit)
— defaults to unlimited
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
setCorePoolSize
setMaxPoolSize
setQueueCapacity
setRejectedExecutionHandler
— 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 ofRunnable
s; the 'default' implementation isThreadPoolTaskScheduler
org.springframework.scheduling.Trigger
— can be used inTaskScheduler::schedule
org.springframework.scheduling.support.CronTrigger
org.springframework.scheduling.support.PeriodicTrigger
TaskExecutor
,org.springframework.scheduling.TaskScheduler
org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
—TaskScheduler
interface wrapping a nativeScheduledThreadPoolExecutor
void setPoolSize(int poolSize)
— pool size defaults to 1
- configuration
@EnableScheduling
org.springframework.scheduling.annotation.SchedulingConfigurer
org.springframework.scheduling.config.ScheduledTaskRegistrar
—set-
,add-
,get-
methodsvoid setTaskScheduler(TaskScheduler taskScheduler)
- scheduled
events
org.springframework.context.ApplicationEvent
org.springframework.context.ApplicationListener<E extends ApplicationEvent>
— only singleton beans@org.springframework.context.event.EventListener
org.springframework.context.ApplicationEventPublisher
org.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.ConcurrentMap
based 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::headers
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
,Pragma: no-cache
X-Content-Type-Options: nosniff
— no MIME-sniffingStrict-Transport-Security: max-age=31536000; includeSubDomains
— only use HTTPSX-Frame-Options
X-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 toSecurityContext
static SecurityContext getContext()
org.springframework.security.core.Authentication
public interface Authentication extends Principal, Serializable
Collection<? 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
— anAuthentication
implementation that is designed for simple presentation of a username and password
org.springframework.security.core.GrantedAuthority
— an authority granted to anAuthentication
objectorg.springframework.security.authentication.AuthenticationManager
— processes anAuthentication
request, default implementationProviderManager
delegates toAuthenticationProvider
implementationsAuthentication authenticate(Authentication authentication)
org.springframework.security.authentication.AuthenticationProvider
— can process a specificAuthentication
implementationAuthentication authenticate(Authentication authentication)
boolean supports(java.lang.Class<?> authentication)
org.springframework.security.authentication.dao.DaoAuthenticationProvider
— anAuthenticationProvider
implementation that retrieves user details from aUserDetailsService
org.springframework.security.core.userdetails.UserDetails
— store user information, such as the username and password,GrantedAuthority
s, and whether the user is enabled, expired, and locked out; which is later encapsulated intoAuthentication
objects, e.g. by authentication providersUserDetailsService::loadUserByUsername
org.springframework.security.core.AuthenticationException
— authentication fail,RuntimeException
org.springframework.security.access.AccessDeniedException
— anAuthentication
object 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 theFilter
interfaceFilterChainProxy
— register security filtersorg.springframework.security.web.SecurityFilterChain
— used byFilterChainProxy
to determine which Spring Security Filters should be invoked for this request
org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer
— registers theDelegatingFilterProxy
to use thespringSecurityFilterChain
before any other registeredFilter
@org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
— add this annotation to an@Configuration
class to have the Spring Security configuration defined in anyWebSecurityConfigurer
or more likely by extending theWebSecurityConfigurerAdapter
base class and overriding individual methodsorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
— a convenient base class for creating aWebSecurityConfigurer
instanceprotected void configure(AuthenticationManagerBuilder auth)
— used by the default implementation ofauthenticationManager()
to attempt to obtain anAuthenticationManager
AuthenticationManager 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 theFilterChainProxy
known as the Spring Security Filter Chain (springSecurityFilterChain
)public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,WebSecurity> implements SecurityBuilder<Filter>, ApplicationContextAware
org.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 addingAuthenticationProvider
spublic 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.event
AbstractAuthenticationFailureEvent
— subclasses indicate more detailed reasons for failureAuthenticationSuccessEvent
— also remember-me authenticationInteractiveAuthenticationSuccessEvent
org.springframework.security.web.authentication.session.SessionFixationProtectionEvent
org.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.EnableGlobalMethodSecurity
boolean jsr250Enabled
boolean securedEnabled
boolean prePostEnabled
org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration
jsr250Enabled
:javax.annotation.security
annotations —@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::authorizeRequests
protected 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 sensitiveanyRequest
antMatchers
—AntPathMatcher
requestMatchers
—RequestMatcher
, simple strategy to match anHttpServletRequest
mvcMatchers
—MvcRequestMatcher
, e.g. for/secured
as well as/secured/
,/secured.html
,/secured.xyz
regexMatchers
—RegexRequestMatcher
org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.AuthorizedUrl
not()
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.Jsr250Voter
org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter
- role
org.springframework.security.access.vote.RoleHierarchyVoter
org.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.ConsensusBased
org.springframework.security.access.vote.UnanimousBased
access control list (or ACL) — tbd
OAuth 2 — tbd
- provider end point —
org.springframework.security.oauth2.provider.endpoint
AuthorizationEndpoint
— for authorization. Default URL:/oauth/authorize
TokenEndpoint
— for access tokens. Default URL:/oauth/token
- authorization server configuration
@EnableAuthorizationServer
AuthorizationServerConfigurer
- resource server filter —
OAuth2AuthenticationProcessingFilter
- provider end point —
# Spring Boot
@org.springframework.boot.autoconfigure.SpringBootApplication
— singleton with arun
method 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@EnableAutoConfiguration
combined Class<?>[] exclude
—exclude
in@EnableAutoConfiguration
- equivalent —
@org.springframework.boot.autoconfigure.EnableAutoConfiguration
— handle@Enable<Technology>
@Target(value=TYPE) @Inherited @AutoConfigurationPackage @Import(value=AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration
AutoConfigurationImportSelector
uses classpath to find all the necessary configuration classesAutoConfigurationImportSelector::getCandidateConfigurations
looks for theMETA-INF/spring.factories
defined in thespring-boot-autoconfigure
jar, 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.exclude
property Class<?>[] exclude
String[] 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.SpringApplicationBuilder
public static void main(String[] args) { new SpringApplicationBuilder() .bannerMode(Banner.Mode.OFF) .sources(SpringBootSimpleApplication.class) .run(args); }
- tbd
- run
ApplicationArguments
—args
fromSpringApplication::run
are 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)); } }
args
format--option_name=value
non_option_args1, non_option_args2
- pass
args
from CLI./mvnw spring-boot:run -Dspring-boot.run.arguments="--enable"
- pass
args
from JAR./mvnw package java -jar spring-boot-simple-0.0.1-SNAPSHOT.jar --enable arg1 arg2
run code after
SpringApplication::run
—ApplicationRunner
andCommandLineRunner
@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 SpringJUnitConfig
Class<?>[] 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 suppliedexpression
evaluates totrue
expression
can be — SpEL,Environment
properties, text literals
@DisabledIf
@SpringBootTest
— works by creating theApplicationContext
used 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); } }