private Stream<BoundCustomizer> eachParameterCustomizers(Parameter parameter, Integer i) {
        final Type parameterType = getParameterType(parameter);
        List<BoundCustomizer> customizers = annotationsFor(parameter)
                .map(a -> instantiateFactory(a).createForParameter(a, sqlObjectType, method, parameter, i, parameterType))
                .<BoundCustomizer>map(c -> new BoundCustomizer() {
                    @Override
                    public void warm(ConfigRegistry config) {
                        c.warm(config);
                    }

                    @Override
                    public void apply(SqlStatement<?> stmt, Object[] args) throws SQLException {
                        c.apply(stmt, args[i]);
                    }
                })
                .collect(Collectors.toList());

        if (!customizers.isEmpty()) {
            return customizers.stream();
        }

        if (parameter.getType() == Consumer.class) {
            if (method.getReturnType() != Void.TYPE) {
                throw new IllegalStateException(
                        "SQL Object methods with a Consumer parameter must have void return type.");
            }
            return Stream.empty();
        }
        if (parameter.getType() == Function.class
            // SqlCallHandler supports Function argument for OutParameters
            && (this instanceof SqlCallHandler
                // SqlBatchHandler, SqlQueryHandler and SqlUpdateHandler support Function arguments
                || this instanceof SqlBatchHandler
                || this instanceof SqlQueryHandler
                || this instanceof SqlUpdateHandler)) {
            return Stream.empty();
        }

        return Stream.of(defaultParameterCustomizer(parameter, i));
    }
Base handler for annotations' implementation classes.
sqlobject/src/main/java/org/jdbi/v3/sqlobject/statement/internal/CustomizingStatementHandler.java