This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch tc-loader
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/tc-loader by this push:
new c2448ea CAMEL-13313: Add support for generating type converter loader
source code to be able to load component type converters in a faster way
c2448ea is described below
commit c2448ead98923e03a4153180372724611d21f5a2
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Mar 18 11:17:22 2019 +0100
CAMEL-13313: Add support for generating type converter loader source code
to be able to load component type converters in a faster way
---
.../modules/ROOT/pages/type-converter.adoc | 210 +++++++--------------
1 file changed, 63 insertions(+), 147 deletions(-)
diff --git a/docs/user-manual/modules/ROOT/pages/type-converter.adoc
b/docs/user-manual/modules/ROOT/pages/type-converter.adoc
index 7ce937b..cbd6e33 100644
--- a/docs/user-manual/modules/ROOT/pages/type-converter.adoc
+++ b/docs/user-manual/modules/ROOT/pages/type-converter.adoc
@@ -36,32 +36,17 @@
http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/TypeCo
interface that can be customized on a
http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/CamelContext.html[CamelContext].
-The default implementation,
-http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/impl/converter/DefaultTypeConverter.html[DefaultTypeConverter],
-uses pluggable strategies to load type converters via
-http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/impl/converter/TypeConverterLoader.html[TypeConverterLoader].
-The default strategy,
-http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/impl/converter/AnnotationTypeConverterLoader.html[AnnotationTypeConverterLoader],
-uses a discovery mechanism to find converters.
-
-*New in Camel 1.5*
-
-The default implementation,
-http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/impl/converter/DefaultTypeConverter.html[DefaultTypeConverter],
-now throws a
-http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/NoTypeConversionAvailableException.html[NoTypeConversionAvailableException]
-if a suitable conversion cannot be found
-(https://issues.apache.org/jira/browse/CAMEL-84[CAMEL-84]).
-The semantical ambiguity of `null` (both valid result and indication
-of no conversion found) is now resolved, but this may impact existing
-code in that it should now catch the exception instead of checking
-for `null`.
+Camel provides two type converter registy implementations:
+
+- FastTypeConverterRegistry (new default)
+- DefaultTypeConverterRegistry (old)
+
+From Camel 3 onwards there is a faster type converter registry implementation
that is enabled by default. This implementation uses source code generation via
the `camel-apt` compiler plugin to generate source code, that allows Camel at
runtime to load and invoke these type converters via quick java method
invocations. The older implementation in Camel 2 uses a annotation based
discover to load and register type converters and invokes the type converters
via Java method call reflections.
+
[[TypeConverter-TypeConverterRegistry]]
==== TypeConverterRegistry
-*New in Camel 2.0*
-
Exposed the
http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/spi/TypeConverterRegistry.html[TypeConverterRegistry]
from link:camelcontext.adoc[CamelContext] so end users more easily will
@@ -84,7 +69,7 @@ Camel can gather utilization statistics of the runtime usage
of type
converters. These stats are available in JMX, and as well as from the
`getStatistics()` method from `TypeConverterRegistry`.
-From *Camel 2.11.0/2.10.5* onwards these statistics are turned off by
+These statistics are turned off by
default as there is some performance overhead under very high concurrent
load. To enable the statistics in Java, do the following:
@@ -103,26 +88,10 @@ Or in the XML DSL with:
</camelContext>
----
-[[TypeConverter-Addtypeconverteratruntime]]
-===== Add type converter at runtime
-
-The following sample demonstrates how to add a type converter at
-runtime: +
-link:../../../camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryTest.java[/camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryTest.java]
-
-And our type converter is implemented as: +
-link:../../../camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryTest.java[/camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryTest.java]
-
-And then we can convert from String to MyOrder as we are used to with the
-type converter: +
-link:../../../camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryTest.java[/camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryTest.java]
-
[[TypeConverter-Addtypeconverterclassesatruntime]]
===== Add type converter classes at runtime
-*Available as of Camel 2.16*
-
-From Camel 2.16 onwards you type converter classes can
+You can add new type converters at runtime, by having your classes
implement `org.apache.camel.TypeConverters` which is an marker
interface. Then for each type converter you want use
the `@Converter` annotation.
@@ -158,30 +127,28 @@ then `CamelContext` will automatic discover and add the
converters.
</camelContext>
----
-You can declare multiple `<bean>`s if you have more clases.
-
-Using this technique do not require to scan the classpath and using the
-file `META-INF/services/org/apache/camel/TypeConverter` as discussed in
-the <<TypeConverter-DiscoveringTypeConverters,Discovering Type Converters>>
-section. However the latter is highly
-recommended when developing Camel components or data formats as then the
-type converters is automatic included out of the box. The functionality
-from this section requires the end users to explicit add the converters
-to their Camel applications.
+You can declare multiple `<bean>`s if you have more classes.
[[TypeConverter-DiscoveringTypeConverters]]
==== Discovering Type Converters
-The
-http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/impl/converter/AnnotationTypeConverterLoader.html[AnnotationTypeConverterLoader]
-will search the classpath for a file called
-`META-INF/services/org/apache/camel/TypeConverter`. The contents are
-expected to be comma separated package names. These packages are then
-recursively searched for any objects with the
-http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/Converter[@Converter]
-annotation. Then any method marked with @Converter is assumed to be a
-conversion method; where the parameter is the from value and the return
-is the to value.
+Camel will automatic discover and load type converters from all the JARs in
the classpath on startup.
+
+Camel will search the classpath for a file called
+`META-INF/services/org/apache/camel/TypeConverterLoader`, which lists
+all type converter loader classes (they are automatic source code generated by
the `camel-apt` compilter plugin).
+These _loader_ classes will load the type converters into the Camel type
converter registry
+and invoking these type converters is done in a _fast way_ using standard java
method calls.
+
+The discover will fallback and discover Camel 2.x compatible type converters by
+search the classpath for a file called
`META-INF/services/org/apache/camel/TypeConverter`,
+which lists all the type converter classes. These classes will then automatic
+be registered in the type converter registry. However invoking these type
converters
+does **not** happen in a _fast way_ but uses Java method call reflection. It
is therefore
+recommended to migrate your type converters to use the faster way. See further
below.
+
+The converter classes must be annotated on the top class level with the
`@Converter` annotation,
+and each converter method as well.
E.g. the following shows how to register a converter from `File` to
`InputStream`:
@@ -197,15 +164,33 @@ public class IOConverter {
}
----
-Static methods are invoked; non-static methods require an instance of
-the converter object to be created (which is then cached). If a
-converter requires configuration you can plug in an Injector interface
-to the `DefaultTypeConverter` which can construct and inject converter
-objects via Spring or Guice.
+===== Discovering Type Converters in the fast way
+
+To enable the fast type converter way, you should enable `loader = true`
+on the class level annotation as shown:
+
+[source,java]
+----
+@Converter(loader = true)
+public class IOConverter {
+ @Converter
+ public static InputStream toInputStream(File file) throws
FileNotFoundException {
+ return new BufferedInputStream(new FileInputStream(file));
+ }
+}
+----
-We have most of the common converters for common Java types in the
-http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/converter/package-summary.html[org.apache.camel.converter]
-package and its children.
+And then you should have the `camel-apt` JAR as dependency when compiling the
project.
+When using Maven you add:
+
+[source,xml]
+----
+<dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>apt</artifactId>
+ <scope>provided</scope>
+</dependency>
+----
[[TypeConverter-Returningnullvalues]]
===== Returning null values
@@ -297,86 +282,19 @@ public static <T> T convertTo(Class<T> type, Exchange
exchange, Object value, Ty
[[TypeConverter-WritingyourownTypeConverters]]
==== Writing your own Type Converters
-[NOTE]
-====
-*Use FQN*
-
-In Camel 2.8 the TypeConverter file now supports specifying the FQN
-class name. This is recommended to be used. See below for more details.
-Using FQN must be used. The older way with just package name is
-deprecated and should not be used, and it may also not work in some
-application servers due to classpath scanning issues.
-====
-
-
You are welcome to write your own converters. Remember to use the
-`@Converter` annotations on the classes and methods you wish to use. Then
-add the packages to a file called
-`META-INF/services/org/apache/camel/TypeConverter` in your jar. Remember
-to make sure that :
+`@Converter` annotations on the classes and methods you wish to use.
+And on the top-level class add `Converter(loader = true)` to support the _fast
way_
+of using type converters.
* static methods are encouraged to reduce caching, but instance methods
are fine, particularly if you want to allow optional dependency
injection to customize the converter
* converter methods should be thread safe and reentrant
-[[TypeConverter-ExamplesofTypeConverterfile]]
-===== Examples of TypeConverter file
-
-The file in the JAR: `META-INF/services/org/apache/camel/TypeConverter`
-contains the following line(s):
-
-----
-com.foo com.bar
-----
-
-Each line in the file is a package name. This tells Camel to go scan
-those packages for any classes that has been annotated with the
-`@Converter`.
-
-[[TypeConverter-ImprovedTypeConverterbyusingFQNclassnames]]
-===== Improved TypeConverter by using FQN class names
-
-*Available as of Camel 2.8*
-
-In Camel 2.8 we improved the type converter loader to support specifying
-the FQN class name of the converter classes. This has the advantage of
-avoiding having to scan packages for `@Converter` classes. Instead it
-loads the `@Converter` class directly. This is a *highly* recommend
-approach to use going forward.
-
-[[TypeConverter-ExamplesofTypeConverterfile.1]]
-===== Examples of TypeConverter file
-
-The file in the JAR: `META-INF/services/org/apache/camel/TypeConverter`
-contains the following line(s) for FQN class names:
-
-----
-com.foo.MyConverter
-com.bar.MyOtherConverter
-com.bar.YetOtherConverter
-----
-
-As you can see each line in the file now contains a FQN class name. This
-is the recommended approach.
-
-[[TypeConverter-Encodingsupportforbyte[]andStringConversion]]
-==== Encoding support for byte[] and String Conversion
-
-*Available in Camel 1.5*
-
-Since Java provides converting the `byte[]` to `String` and `String` to
`byte[]`
-with the
-http://java.sun.com/j2se/1.5.0/docs/api/java/nio/charset/Charset.html[charset
-name] parameter. You can define the charset name by setting the exchange
-property name `Exchange.CHARSET_NAME` with the charset name, such as
-`"UTF-8"` or `"iso-8859-1"`.
-
[[TypeConverter-Exchangeparameter]]
==== Exchange parameter
-*Available in Camel 1.5*
-
The type converter accepts the `Exchange` as an optional 2nd parameter.
This is usable if the type converter for instance needs information from
the current exchange. For instance combined with the encoding support
@@ -388,16 +306,14 @@ converter:
----
@Converter
public static String toString(byte[] data, Exchange exchange) {
- if (exchange != null) {
- String charsetName = exchange.getProperty(Exchange.CHARSET_NAME,
String.class);
- if (charsetName != null) {
- try {
- return new String(data, charsetName);
- } catch (UnsupportedEncodingException e) {
- LOG.warn("Can't convert the byte to String with the charset "
+ charsetName, e);
- }
+ String charsetName = exchange.getProperty(Exchange.CHARSET_NAME,
String.class);
+ if (charsetName != null) {
+ try {
+ return new String(data, charsetName);
+ } catch (UnsupportedEncodingException e) {
+ // ignore
}
+ return new String(data);
}
- return new String(data);
}
----