FactoryBean, BeanPostProcessor and HandlerInterceptor variants declared with default methods

Issue: SPR-14432
This commit is contained in:
Juergen Hoeller 2016-07-06 15:10:08 +02:00
parent e4b0486c5a
commit 76dedd7ca2
8 changed files with 76 additions and 27 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -111,10 +111,14 @@ public interface FactoryBean<T> {
* implementations which do not implement this extended interface are
* simply assumed to always return independent instances if the
* {@code isSingleton()} implementation returns {@code false}.
* <p>The default implementation returns {@code true}, since a
* {@code FactoryBean} typically manages a singleton instance.
* @return whether the exposed object is a singleton
* @see #getObject()
* @see SmartFactoryBean#isPrototype()
*/
boolean isSingleton();
default boolean isSingleton() {
return true;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -35,6 +35,7 @@ import org.springframework.beans.BeansException;
* @since 1.0.2
* @see FactoryBean
*/
@FunctionalInterface
public interface ObjectFactory<T> {
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -50,11 +50,14 @@ public interface SmartFactoryBean<T> extends FactoryBean<T> {
* it should not return {@code true} for scoped objects or other
* kinds of non-singleton, non-independent objects. For this reason,
* this is not simply the inverted form of {@link #isSingleton()}.
* <p>The default implementation returns {@code false}.
* @return whether the exposed object is a prototype
* @see #getObject()
* @see #isSingleton()
*/
boolean isPrototype();
default boolean isPrototype() {
return false;
}
/**
* Does this FactoryBean expect eager initialization, that is,
@ -67,9 +70,12 @@ public interface SmartFactoryBean<T> extends FactoryBean<T> {
* also applying post-processors eagerly. This may make sense in case
* of a {@link #isSingleton() singleton} object, in particular if
* post-processors expect to be applied on startup.
* <p>The default implementation returns {@code false}.
* @return whether eager initialization applies
* @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons()
*/
boolean isEagerInit();
default boolean isEagerInit() {
return false;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -46,6 +46,7 @@ public interface BeanPostProcessor {
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* <p>The default implementation returns the given {@code bean} as-is.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
@ -53,7 +54,9 @@ public interface BeanPostProcessor {
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
@ -67,6 +70,7 @@ public interface BeanPostProcessor {
* <p>This callback will also be invoked after a short-circuiting triggered by a
* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
* in contrast to all other BeanPostProcessor callbacks.
* <p>The default implementation returns the given {@code bean} as-is.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
@ -75,6 +79,8 @@ public interface BeanPostProcessor {
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.FactoryBean
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -61,6 +61,8 @@ public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
* be called for this bean instance eventually, or {@code false} if not needed
* @since 4.3
*/
boolean requiresDestruction(Object bean);
default boolean requiresDestruction(Object bean) {
return true;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -58,6 +58,7 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
* <p>Post-processors may implement the extended
* {@link SmartInstantiationAwareBeanPostProcessor} interface in order
* to predict the type of the bean object that they are going to return here.
* <p>The default implementation returns {@code null}.
* @param beanClass the class of the bean to be instantiated
* @param beanName the name of the bean
* @return the bean object to expose instead of a default instance of the target bean,
@ -66,7 +67,9 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#hasBeanClass
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#getFactoryMethodName
*/
Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* Perform operations after the bean has been instantiated, via a constructor or factory method,
@ -74,6 +77,7 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
* <p>This is the ideal callback for performing field injection on the given bean instance.
* See Spring's own {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor}
* for a typical example.
* <p>The default implementation returns {@code true}.
* @param bean the bean instance created, with properties not having been set yet
* @param beanName the name of the bean
* @return {@code true} if properties should be set on the bean; {@code false}
@ -82,7 +86,9 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
* instances being invoked on this bean instance.
* @throws org.springframework.beans.BeansException in case of errors
*/
boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
/**
* Post-process the given property values before the factory applies them
@ -91,6 +97,7 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
* <p>Also allows for replacing the property values to apply, typically through
* creating a new MutablePropertyValues instance based on the original PropertyValues,
* adding or removing specific values.
* <p>The default implementation returns the given {@code pvs} as-is.
* @param pvs the property values that the factory is about to apply (never {@code null})
* @param pds the relevant property descriptors for the target bean (with ignored
* dependency types - which the factory handles specifically - already filtered out)
@ -102,8 +109,10 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.MutablePropertyValues
*/
PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException;
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -39,21 +39,29 @@ public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationA
/**
* Predict the type of the bean to be eventually returned from this
* processor's {@link #postProcessBeforeInstantiation} callback.
* <p>The default implementation returns {@code null}.
* @param beanClass the raw class of the bean
* @param beanName the name of the bean
* @return the type of the bean, or {@code null} if not predictable
* @throws org.springframework.beans.BeansException in case of errors
*/
Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException;
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* Determine the candidate constructors to use for the given bean.
* <p>The default implementation returns {@code null}.
* @param beanClass the raw class of the bean (never {@code null})
* @param beanName the name of the bean
* @return the candidate constructors, or {@code null} if none specified
* @throws org.springframework.beans.BeansException in case of errors
*/
Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException;
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
/**
* Obtain a reference for early access to the specified bean,
@ -69,12 +77,15 @@ public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationA
* return the raw bean instance from those subsequent callbacks (if the wrapper
* for the affected bean has been built for a call to this method already,
* it will be exposes as final bean reference by default).
* <p>The default implementation returns the given {@code bean} as-is.
* @param bean the raw bean instance
* @param beanName the name of the bean
* @return the object to expose as bean reference
* (typically with the passed-in bean instance as default)
* @throws org.springframework.beans.BeansException in case of errors
*/
Object getEarlyBeanReference(Object bean, String beanName) throws BeansException;
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}

View File

@ -84,6 +84,7 @@ public interface HandlerInterceptor {
* <p><strong>Note:</strong> special considerations apply for asynchronous
* request processing. For more details see
* {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
* <p>The default implementation returns {@code true}.
* @param request current HTTP request
* @param response current HTTP response
* @param handler chosen handler to execute, for type and/or instance evaluation
@ -92,8 +93,11 @@ public interface HandlerInterceptor {
* that this interceptor has already dealt with the response itself.
* @throws Exception in case of errors
*/
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception;
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
/**
* Intercept the execution of a handler. Called after HandlerAdapter actually
@ -106,6 +110,7 @@ public interface HandlerInterceptor {
* <p><strong>Note:</strong> special considerations apply for asynchronous
* request processing. For more details see
* {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
* <p>The default implementation is empty.
* @param request current HTTP request
* @param response current HTTP response
* @param handler handler (or {@link HandlerMethod}) that started asynchronous
@ -114,8 +119,10 @@ public interface HandlerInterceptor {
* (can also be {@code null})
* @throws Exception in case of errors
*/
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception;
default void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
}
/**
* Callback after completion of request processing, that is, after rendering
@ -129,6 +136,7 @@ public interface HandlerInterceptor {
* <p><strong>Note:</strong> special considerations apply for asynchronous
* request processing. For more details see
* {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
* <p>The default implementation is empty.
* @param request current HTTP request
* @param response current HTTP response
* @param handler handler (or {@link HandlerMethod}) that started asynchronous
@ -136,7 +144,9 @@ public interface HandlerInterceptor {
* @param ex exception thrown on handler execution, if any
* @throws Exception in case of errors
*/
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception;
default void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}