diff --git a/spring-context/src/main/java/org/springframework/context/Lifecycle.java b/spring-context/src/main/java/org/springframework/context/Lifecycle.java index 16060116bb77..3cda24bbfe5a 100644 --- a/spring-context/src/main/java/org/springframework/context/Lifecycle.java +++ b/spring-context/src/main/java/org/springframework/context/Lifecycle.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2018 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. @@ -34,10 +34,11 @@ * restricting the visibility of activity-controlled components to the Lifecycle * interface. * - *

Note that the Lifecycle interface is only supported on top-level singleton - * beans. On any other component, the Lifecycle interface will remain undetected - * and hence ignored. Also, note that the extended {@link SmartLifecycle} interface - * provides integration with the application context's startup and shutdown phases. + *

Note that the present {@code Lifecycle} interface is only supported on + * top-level singleton beans. On any other component, the {@code Lifecycle} + * interface will remain undetected and hence ignored. Also, note that the extended + * {@link SmartLifecycle} interface provides sophisticated integration with the + * application context's startup and shutdown phases. * * @author Juergen Hoeller * @since 2.0 @@ -61,11 +62,12 @@ public interface Lifecycle { * Stop this component, typically in a synchronous fashion, such that the component is * fully stopped upon return of this method. Consider implementing {@link SmartLifecycle} * and its {@code stop(Runnable)} variant when asynchronous stop behavior is necessary. - *

Note that this stop notification is not guaranteed to come before destruction: On - * regular shutdown, {@code Lifecycle} beans will first receive a stop notification before - * the general destruction callbacks are being propagated; however, on hot refresh during a - * context's lifetime or on aborted refresh attempts, only destroy methods will be called. - *

Should not throw an exception if the component isn't started yet. + *

Note that this stop notification is not guaranteed to come before destruction: + * On regular shutdown, {@code Lifecycle} beans will first receive a stop notification + * before the general destruction callbacks are being propagated; however, on hot + * refresh during a context's lifetime or on aborted refresh attempts, a given bean's + * destroy method will be called without any consideration of stop signals upfront. + *

Should not throw an exception if the component is not running (not started yet). *

In the case of a container, this will propagate the stop signal to all components * that apply. * @see SmartLifecycle#stop(Runnable) diff --git a/spring-context/src/main/java/org/springframework/context/SmartLifecycle.java b/spring-context/src/main/java/org/springframework/context/SmartLifecycle.java index 1ae2c12e9de5..d392c721dacd 100644 --- a/spring-context/src/main/java/org/springframework/context/SmartLifecycle.java +++ b/spring-context/src/main/java/org/springframework/context/SmartLifecycle.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2018 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. @@ -23,35 +23,35 @@ * be started at the time of a context refresh. The callback-accepting * {@link #stop(Runnable)} method is useful for objects that have an asynchronous * shutdown process. Any implementation of this interface must invoke the - * callback's run() method upon shutdown completion to avoid unnecessary delays - * in the overall ApplicationContext shutdown. + * callback's {@code run()} method upon shutdown completion to avoid unnecessary + * delays in the overall ApplicationContext shutdown. * *

This interface extends {@link Phased}, and the {@link #getPhase()} method's * return value indicates the phase within which this Lifecycle component should - * be started and stopped. The startup process begins with the lowest - * phase value and ends with the highest phase value (Integer.MIN_VALUE - * is the lowest possible, and Integer.MAX_VALUE is the highest possible). The - * shutdown process will apply the reverse order. Any components with the + * be started and stopped. The startup process begins with the lowest phase + * value and ends with the highest phase value ({@code Integer.MIN_VALUE} + * is the lowest possible, and {@code Integer.MAX_VALUE} is the highest possible). + * The shutdown process will apply the reverse order. Any components with the * same value will be arbitrarily ordered within the same phase. * - *

Example: if component B depends on component A having already started, then - * component A should have a lower phase value than component B. During the - * shutdown process, component B would be stopped before component A. + *

Example: if component B depends on component A having already started, + * then component A should have a lower phase value than component B. During + * the shutdown process, component B would be stopped before component A. * - *

Any explicit "depends-on" relationship will take precedence over - * the phase order such that the dependent bean always starts after its - * dependency and always stops before its dependency. + *

Any explicit "depends-on" relationship will take precedence over the phase + * order such that the dependent bean always starts after its dependency and + * always stops before its dependency. * - *

Any Lifecycle components within the context that do not also implement - * SmartLifecycle will be treated as if they have a phase value of 0. That - * way a SmartLifecycle implementation may start before those Lifecycle - * components if it has a negative phase value, or it may start after - * those components if it has a positive phase value. + *

Any {@code Lifecycle} components within the context that do not also + * implement {@code SmartLifecycle} will be treated as if they have a phase + * value of 0. That way a {@code SmartLifecycle} implementation may start + * before those {@code Lifecycle} components if it has a negative phase value, + * or it may start after those components if it has a positive phase value. * - *

Note that, due to the auto-startup support in SmartLifecycle, - * a SmartLifecycle bean instance will get initialized on startup of the - * application context in any case. As a consequence, the bean definition - * lazy-init flag has very limited actual effect on SmartLifecycle beans. + *

Note that, due to the auto-startup support in {@code SmartLifecycle}, a + * {@code SmartLifecycle} bean instance will usually get initialized on startup + * of the application context in any case. As a consequence, the bean definition + * lazy-init flag has very limited actual effect on {@code SmartLifecycle} beans. * * @author Mark Fisher * @since 3.0 diff --git a/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java b/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java index 174496e9c4ae..6775937da52f 100644 --- a/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java @@ -187,11 +187,11 @@ private void stopBeans() { Map phases = new HashMap(); for (Map.Entry entry : lifecycleBeans.entrySet()) { Lifecycle bean = entry.getValue(); - int shutdownOrder = getPhase(bean); - LifecycleGroup group = phases.get(shutdownOrder); + int shutdownPhase = getPhase(bean); + LifecycleGroup group = phases.get(shutdownPhase); if (group == null) { - group = new LifecycleGroup(shutdownOrder, this.timeoutPerShutdownPhase, lifecycleBeans, false); - phases.put(shutdownOrder, group); + group = new LifecycleGroup(shutdownPhase, this.timeoutPerShutdownPhase, lifecycleBeans, false); + phases.put(shutdownPhase, group); } group.add(entry.getKey(), bean); } @@ -291,11 +291,11 @@ protected Map getLifecycleBeans() { /** * Determine the lifecycle phase of the given bean. - *

The default implementation checks for the {@link Phased} interface. - * Can be overridden to apply other/further policies. + *

The default implementation checks for the {@link Phased} interface, using + * a default of 0 otherwise. Can be overridden to apply other/further policies. * @param bean the bean to introspect - * @return the phase an integer value. The suggested default is 0. - * @see Phased + * @return the phase (an integer value) + * @see Phased#getPhase() * @see SmartLifecycle */ protected int getPhase(Lifecycle bean) { @@ -402,9 +402,9 @@ private class LifecycleGroupMember implements Comparable { @Override public int compareTo(LifecycleGroupMember other) { - int thisOrder = getPhase(this.bean); - int otherOrder = getPhase(other.bean); - return (thisOrder == otherOrder ? 0 : (thisOrder < otherOrder) ? -1 : 1); + int thisPhase = getPhase(this.bean); + int otherPhase = getPhase(other.bean); + return (thisPhase == otherPhase ? 0 : (thisPhase < otherPhase) ? -1 : 1); } } diff --git a/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistry.java b/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistry.java index 4d48fb31fed7..56c211cea375 100644 --- a/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistry.java +++ b/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 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. @@ -100,8 +100,8 @@ public MessageListenerContainer getListenerContainer(String id) { /** * Return the ids of the managed {@link MessageListenerContainer} instance(s). - * @see #getListenerContainer(String) * @since 4.2.3 + * @see #getListenerContainer(String) */ public Set getListenerContainerIds() { return Collections.unmodifiableSet(this.listenerContainers.keySet()); @@ -131,9 +131,9 @@ public void registerListenerContainer(JmsListenerEndpoint endpoint, JmsListenerC Assert.notNull(endpoint, "Endpoint must not be null"); Assert.notNull(factory, "Factory must not be null"); - String id = endpoint.getId(); Assert.notNull(id, "Endpoint id must not be null"); + synchronized (this.listenerContainers) { if (this.listenerContainers.containsKey(id)) { throw new IllegalStateException("Another endpoint is already registered with id '" + id + "'"); @@ -191,13 +191,13 @@ protected MessageListenerContainer createListenerContainer(JmsListenerEndpoint e // Delegating implementation of SmartLifecycle @Override - public int getPhase() { - return this.phase; + public boolean isAutoStartup() { + return true; } @Override - public boolean isAutoStartup() { - return true; + public int getPhase() { + return this.phase; } @Override diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java index 1c67f32f9d70..6182a37f7a18 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java @@ -231,7 +231,7 @@ public Validator getValidator() { } /** - * Set the Validator instance used for validating @Payload arguments + * Set the Validator instance used for validating {@code @Payload} arguments. * @see org.springframework.validation.annotation.Validated * @see PayloadArgumentResolver */ diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java index c6383aff04a8..87334a3fa89c 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java @@ -143,13 +143,13 @@ public MessageHeaderInitializer getHeaderInitializer() { @Override - public int getPhase() { - return Integer.MAX_VALUE; + public boolean isAutoStartup() { + return true; } @Override - public boolean isAutoStartup() { - return true; + public int getPhase() { + return Integer.MAX_VALUE; } @Override diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java index 3d734fe96890..b401b52502ef 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java @@ -131,13 +131,11 @@ public ModelAndView resolveException( prepareResponse(ex, response); ModelAndView result = doResolveException(request, response, handler, ex); if (result != null) { - - // Print warn message, when warn logger is not enabled.. + // Print warn message when warn logger is not enabled... if (logger.isWarnEnabled() && (this.warnLogger == null || !this.warnLogger.isWarnEnabled())) { logger.warn("Resolved [" + ex + "]" + (result.isEmpty() ? "" : " to " + result)); } - - // warnLogger with full stack trace (requires explicit config).. + // warnLogger with full stack trace (requires explicit config) logException(ex, request); } return result; @@ -200,7 +198,7 @@ protected void logException(Exception ex, HttpServletRequest request) { * @return the log message to use */ protected String buildLogMessage(Exception ex, HttpServletRequest request) { - return "Resolved exception caused by Handler execution: " + ex; + return "Resolved exception caused by handler execution: " + ex; } /** diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/messaging/WebSocketStompClient.java b/spring-websocket/src/main/java/org/springframework/web/socket/messaging/WebSocketStompClient.java index baa6aedb21de..4ec780a79431 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/messaging/WebSocketStompClient.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/messaging/WebSocketStompClient.java @@ -211,8 +211,8 @@ public boolean isRunning() { * when connected on the STOMP level after the CONNECTED frame is received. * @param url the url to connect to * @param handler the session handler - * @param uriVars URI variables to expand into the URL - * @return ListenableFuture for access to the session when ready for use + * @param uriVars the URI variables to expand into the URL + * @return a ListenableFuture for access to the session when ready for use */ public ListenableFuture connect(String url, StompSessionHandler handler, Object... uriVars) { return connect(url, null, handler, uriVars); @@ -225,8 +225,8 @@ public ListenableFuture connect(String url, StompSessionHandler ha * @param url the url to connect to * @param handshakeHeaders the headers for the WebSocket handshake * @param handler the session handler - * @param uriVariables URI variables to expand into the URL - * @return ListenableFuture for access to the session when ready for use + * @param uriVariables the URI variables to expand into the URL + * @return a ListenableFuture for access to the session when ready for use */ public ListenableFuture connect(String url, WebSocketHttpHeaders handshakeHeaders, StompSessionHandler handler, Object... uriVariables) { @@ -243,8 +243,8 @@ public ListenableFuture connect(String url, WebSocketHttpHeaders h * @param handshakeHeaders headers for the WebSocket handshake * @param connectHeaders headers for the STOMP CONNECT frame * @param handler the session handler - * @param uriVariables URI variables to expand into the URL - * @return ListenableFuture for access to the session when ready for use + * @param uriVariables the URI variables to expand into the URL + * @return a ListenableFuture for access to the session when ready for use */ public ListenableFuture connect(String url, WebSocketHttpHeaders handshakeHeaders, StompHeaders connectHeaders, StompSessionHandler handler, Object... uriVariables) { @@ -262,7 +262,7 @@ public ListenableFuture connect(String url, WebSocketHttpHeaders h * @param handshakeHeaders the headers for the WebSocket handshake * @param connectHeaders headers for the STOMP CONNECT frame * @param sessionHandler the STOMP session handler - * @return ListenableFuture for access to the session when ready for use + * @return a ListenableFuture for access to the session when ready for use */ public ListenableFuture connect(URI url, WebSocketHttpHeaders handshakeHeaders, StompHeaders connectHeaders, StompSessionHandler sessionHandler) { @@ -392,7 +392,10 @@ public ListenableFuture send(Message message) { } private void updateLastWriteTime() { - this.lastWriteTime = (this.lastWriteTime != -1 ? System.currentTimeMillis() : -1); + long lastWriteTime = this.lastWriteTime; + if (lastWriteTime != -1) { + this.lastWriteTime = System.currentTimeMillis(); + } } @Override diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHandlerMapping.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHandlerMapping.java index 2cd4eb9d53b7..ca8f12a755b6 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHandlerMapping.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 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 @@ protected void initServletContext(ServletContext servletContext) { } } + @Override public boolean isAutoStartup() { return true;