INT-4270: CGLib Compatibility

JIRA: https://jira.spring.io/browse/INT-4270

Initial Commit

Remove `final` modifier from certain critical framework methods that prevent CGLib proxies working.

Since Spring Boot 2.0 now uses proxyTargetClass=true by default (and has done that for
transactional proxies since 1.4), we must relax these restrictions so that CGLib can
proxy channels (which is often done to make subflows run in a transaction).

When CGLib can't override a `final` method, the fields used within those methods are uninitialized.
In the case of `AbstractMessageChannel` this causes an NPE on the unitiallized `dataTypes` field.
With `MessageHandler`, fields like `shouldTrack` are always false.

Further, methods on `IntegrationObjectSupport` - such as `getComponentName()` return null.

I have left setters and `afterPropertiesSet` (on IOS) `final` since these will typically be called
before the object is proxied.

I suspect there will be other methods we need to open up, but perhaps we should only do them on-demand.

__cherry-pick to 4.3.x__
This commit is contained in:
Gary Russell
2017-05-04 17:55:06 -04:00
committed by Artem Bilan
parent 168f372dd4
commit 2b4c343eaa
6 changed files with 251 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -369,7 +369,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
* <code>false</code> if the sending thread is interrupted.
*/
@Override
public final boolean send(Message<?> message) {
public boolean send(Message<?> message) {
return this.send(message, -1);
}
@@ -388,7 +388,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
* time or the sending thread is interrupted.
*/
@Override
public final boolean send(Message<?> message, long timeout) {
public boolean send(Message<?> message, long timeout) {
Assert.notNull(message, "message must not be null");
Assert.notNull(message.getPayload(), "message payload must not be null");
if (this.shouldTrack) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@@ -68,7 +68,7 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel
* receiving thread is interrupted.
*/
@Override
public final Message<?> receive() {
public Message<?> receive() {
return receive(-1);
}
@@ -86,7 +86,7 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel
* interrupted.
*/
@Override
public final Message<?> receive(long timeout) {
public Message<?> receive(long timeout) {
ChannelInterceptorList interceptorList = getInterceptors();
Deque<ChannelInterceptor> interceptorStack = null;
boolean counted = false;

View File

@@ -105,7 +105,7 @@ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedCo
* If {@link #componentName} was not set this method will default to the 'beanName' of this component;
*/
@Override
public final String getComponentName() {
public String getComponentName() {
return StringUtils.hasText(this.componentName) ? this.componentName : this.beanName;
}
@@ -190,7 +190,7 @@ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedCo
protected void onInit() throws Exception {
}
protected final BeanFactory getBeanFactory() {
protected BeanFactory getBeanFactory() {
return this.beanFactory;
}
@@ -213,7 +213,7 @@ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedCo
this.taskScheduler = taskScheduler;
}
public final ConversionService getConversionService() {
public ConversionService getConversionService() {
if (this.conversionService == null && this.beanFactory != null) {
synchronized (this) {
if (this.conversionService == null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -136,7 +136,7 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport im
}
@Override
public final void handleMessage(Message<?> message) {
public void handleMessage(Message<?> message) {
Assert.notNull(message, "Message must not be null");
Assert.notNull(message.getPayload(), "Message payload must not be null"); //NOSONAR - false positive
if (this.loggingEnabled && this.logger.isDebugEnabled()) {