Parameter factories provide flexible mechanisms for extracting SQL parameters from Spring Integration messages and message payloads. They enable SpEL expressions, bean property mapping, static parameters, and custom parameter extraction strategies for JDBC operations.
Required Dependencies:
spring-integration-jdbc (this package)spring-integration-core is requiredBeanFactory required for ExpressionEvaluatingSqlParameterSourceFactory (for bean references in expressions)Default Behaviors:
BeanPropertySqlParameterSourceFactory (extracts bean properties or map keys)usePayloadAsParameterSource=true (only payload used, not headers)Threading Model:
ParameterSourceFactory instances should be thread-safe (reusable)Lifecycle:
ParameterSourceFactory instances are typically Spring beans (singleton)ParameterSource instances are created per message (short-lived)Exceptions:
IllegalArgumentException - Invalid parameter name or configurationEvaluationException - SpEL expression evaluation failuresPropertyAccessException - Bean property access failuresNoSuchParameterException - Parameter not found in source (when accessing)Edge Cases:
hasValue() returns false, getValue() may return null or throw exceptionBeanPropertySqlParameterSource uses Spring's BeanWrapper for property access:customer.name)createParameterSourceNoCache())@beanName syntax@environment.getProperty()package org.springframework.integration.jdbc;
@FunctionalInterface
public interface SqlParameterSourceFactory {
SqlParameterSource createParameterSource(Object input);
}package org.springframework.integration.jdbc;
public class BeanPropertySqlParameterSourceFactory implements SqlParameterSourceFactory {
public void setStaticParameters(Map<String, Object> staticParameters);
public SqlParameterSource createParameterSource(Object input);
}package org.springframework.integration.jdbc;
public class ExpressionEvaluatingSqlParameterSourceFactory
extends AbstractExpressionEvaluator implements SqlParameterSourceFactory {
public void setStaticParameters(Map<String, Object> staticParameters);
public void setParameterExpressions(Map<String, String> parameterExpressions);
public void setSqlParameterTypes(Map<String, Integer> sqlParametersTypes);
public SqlParameterSource createParameterSource(Object input);
public SqlParameterSource createParameterSourceNoCache(Object input);
}import org.springframework.integration.jdbc.SqlParameterSourceFactory;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
// Lambda implementation for simple mapping
SqlParameterSourceFactory simpleFactory = input -> {
Order order = (Order) input;
return new MapSqlParameterSource()
.addValue("orderId", order.getId())
.addValue("amount", order.getAmount())
.addValue("status", order.getStatus());
};
// Use in JDBC handler
JdbcMessageHandler handler = new JdbcMessageHandler(
dataSource,
"INSERT INTO orders (order_id, amount, status) VALUES (:orderId, :amount, :status)"
);
handler.setSqlParameterSourceFactory(simpleFactory);import org.springframework.integration.jdbc.BeanPropertySqlParameterSourceFactory;
// Basic bean property mapping
BeanPropertySqlParameterSourceFactory beanFactory =
new BeanPropertySqlParameterSourceFactory();
// Given Order bean with getId(), getOrderNumber(), getAmount()
// Creates parameters: :id, :orderNumber, :amount
JdbcMessageHandler handler = new JdbcMessageHandler(
dataSource,
"INSERT INTO orders (id, order_number, amount) VALUES (:id, :orderNumber, :amount)"
);
handler.setSqlParameterSourceFactory(beanFactory);
handler.setUsePayloadAsParameterSource(true);
// Send Order object as payload
Order order = new Order(123L, "ORD-456", new BigDecimal("99.99"));
handler.handleMessage(MessageBuilder.withPayload(order).build());// Static parameters combined with dynamic values
BeanPropertySqlParameterSourceFactory factoryWithStatics =
new BeanPropertySqlParameterSourceFactory();
Map<String, Object> staticParams = Map.of(
"source", "WEB_APP",
"version", "2.0",
"region", "US-WEST"
);
factoryWithStatics.setStaticParameters(staticParams);
JdbcMessageHandler staticHandler = new JdbcMessageHandler(
dataSource,
"INSERT INTO events (event_type, data, source, version, region) " +
"VALUES (:eventType, :data, :source, :version, :region)"
);
staticHandler.setSqlParameterSourceFactory(factoryWithStatics);
// Only need to provide eventType and data; static params added automatically
Event event = new Event("USER_LOGIN", "user data");
staticHandler.handleMessage(MessageBuilder.withPayload(event).build());import org.springframework.integration.jdbc.ExpressionEvaluatingSqlParameterSourceFactory;
// Basic expression mapping
ExpressionEvaluatingSqlParameterSourceFactory exprFactory =
new ExpressionEvaluatingSqlParameterSourceFactory();
Map<String, String> expressions = Map.of(
"orderId", "payload.id",
"orderNumber", "payload.orderNumber",
"totalAmount", "payload.amount"
);
exprFactory.setParameterExpressions(expressions);
JdbcMessageHandler handler = new JdbcMessageHandler(
dataSource,
"INSERT INTO orders (order_id, order_number, total_amount) " +
"VALUES (:orderId, :orderNumber, :totalAmount)"
);
handler.setSqlParameterSourceFactory(exprFactory);
handler.setUsePayloadAsParameterSource(false); // Process entire message// Expressions with calculations and transformations
ExpressionEvaluatingSqlParameterSourceFactory calcFactory =
new ExpressionEvaluatingSqlParameterSourceFactory();
Map<String, String> calcExpressions = Map.of(
"orderId", "payload.id",
"subtotal", "payload.items.![price * quantity].sum()",
"tax", "payload.items.![price * quantity].sum() * 0.08",
"total", "payload.items.![price * quantity].sum() * 1.08",
"itemCount", "payload.items.size()"
);
calcFactory.setParameterExpressions(calcExpressions);// Access message headers
ExpressionEvaluatingSqlParameterSourceFactory headerFactory =
new ExpressionEvaluatingSqlParameterSourceFactory();
Map<String, String> headerExpressions = Map.of(
"orderId", "payload.id",
"userId", "headers['user-id']",
"correlationId", "headers['correlation-id']",
"timestamp", "headers.timestamp",
"priority", "headers.priority != null ? headers.priority : 0"
);
headerFactory.setParameterExpressions(headerExpressions);Parameter factories integrate with all JDBC message handlers and gateways:
// Inbound adapter update parameters
JdbcPollingChannelAdapter adapter = new JdbcPollingChannelAdapter(
dataSource,
"SELECT * FROM orders WHERE processed = false"
);
ExpressionEvaluatingSqlParameterSourceFactory updateFactory =
new ExpressionEvaluatingSqlParameterSourceFactory();
updateFactory.setParameterExpressions(Map.of(
"id", "id",
"processedAt", "T(System).currentTimeMillis()",
"processedBy", "@environment.getProperty('instance.id')"
));
adapter.setUpdateSql("UPDATE orders SET processed = true, processed_at = :processedAt, processed_by = :processedBy WHERE id = :id");
adapter.setUpdateSqlParameterSourceFactory(updateFactory);usePayloadAsParameterSource=false to access headers in expressions@beanName syntax@environment.getProperty()