Java源码示例:org.springframework.cloud.function.context.FunctionRegistration
示例1
private void registerExport(GenericApplicationContext context) {
context.registerBean(ExporterProperties.class, () -> new ExporterProperties());
context.registerBean(FunctionExporterAutoConfiguration.class,
() -> new FunctionExporterAutoConfiguration(context.getBean(ExporterProperties.class)));
if (context.getBeanFactory().getBeanNamesForType(DestinationResolver.class, false, false).length == 0) {
context.registerBean(DestinationResolver.class,
() -> context.getBean(FunctionExporterAutoConfiguration.class).simpleDestinationResolver());
}
if (context.getBeanFactory().getBeanNamesForType(RequestBuilder.class, false, false).length == 0) {
context.registerBean(RequestBuilder.class, () -> context.getBean(FunctionExporterAutoConfiguration.class)
.simpleRequestBuilder(context.getEnvironment()));
}
if (context.getEnvironment().getProperty("spring.cloud.function.web.export.source.url") != null) {
context.registerBean("origin", FunctionRegistration.class, () -> context
.getBean(FunctionExporterAutoConfiguration.class).origin(context.getBean(WebClient.Builder.class)));
}
if (context.getEnvironment().getProperty("spring.cloud.function.web.export.sink.url") != null) {
context.registerBean(SupplierExporter.class,
() -> context.getBean(FunctionExporterAutoConfiguration.class).sourceForwarder(
context.getBean(RequestBuilder.class), context.getBean(DestinationResolver.class),
context.getBean(FunctionCatalog.class), context.getBean(WebClient.Builder.class)));
}
}
示例2
@Override
Object locateFunction(String name) {
Object function = super.locateFunction(name);
if (function == null) {
try {
function = BeanFactoryAnnotationUtils.qualifiedBeanOfType(this.applicationContext.getBeanFactory(), Object.class, name);
}
catch (Exception e) {
// ignore
}
}
if (function == null && this.applicationContext.containsBean(name)) {
function = this.applicationContext.getBean(name);
}
if (function != null && this.notFunction(function.getClass())
&& this.applicationContext
.containsBean(name + FunctionRegistration.REGISTRATION_NAME_SUFFIX)) { // e.g., Kotlin lambdas
function = this.applicationContext
.getBean(name + FunctionRegistration.REGISTRATION_NAME_SUFFIX, FunctionRegistration.class);
}
return function;
}
示例3
private static void assertSupportedTypes(Type type) {
if (type instanceof ParameterizedType) {
type = ((ParameterizedType) type).getRawType();
Assert.isTrue(type instanceof Class<?>, "Must be one of Supplier, Function, Consumer"
+ " or FunctionRegistration. Was " + type);
}
Class<?> candidateType = (Class<?>) type;
Assert.isTrue(Supplier.class.isAssignableFrom(candidateType)
|| Function.class.isAssignableFrom(candidateType)
|| Consumer.class.isAssignableFrom(candidateType)
|| FunctionRegistration.class.isAssignableFrom(candidateType)
|| type.getTypeName().startsWith("org.springframework.context.annotation.ConfigurationClassEnhancer"), "Must be one of Supplier, Function, Consumer"
+ " or FunctionRegistration. Was " + type);
}
示例4
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof FunctionRegistry) {
FunctionRegistry catalog = (FunctionRegistry) bean;
for (FunctionRegistration<?> registration : this.functions) {
Assert.notEmpty(registration.getNames(),
"FunctionRegistration must define at least one name. Was empty");
if (registration.getType() == null) {
throw new IllegalStateException(
"You need an explicit type for the function: " + registration.getNames());
// TODO: in principle Spring could know how to extract this
// from the supplier, but in practice there is no functional
// bean registration with parametric types.
}
catalog.register(registration);
}
}
return bean;
}
示例5
@Test
public void testFunctionLookup() {
TestFunction function = new TestFunction();
FunctionRegistration<TestFunction> registration = new FunctionRegistration<>(
function, "foo").type(FunctionType.of(TestFunction.class));
SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
catalog.register(registration);
FunctionInvocationWrapper lookedUpFunction = catalog.lookup("hello");
assertThat(lookedUpFunction).isNotNull(); // because we only have one and can look it up with any name
FunctionRegistration<TestFunction> registration2 = new FunctionRegistration<>(
function, "foo2").type(FunctionType.of(TestFunction.class));
catalog.register(registration2);
lookedUpFunction = catalog.lookup("hello");
assertThat(lookedUpFunction).isNull();
}
示例6
@Test
public void testFunctionComposition() {
FunctionRegistration<UpperCase> upperCaseRegistration = new FunctionRegistration<>(
new UpperCase(), "uppercase").type(FunctionType.of(UpperCase.class));
FunctionRegistration<Reverse> reverseRegistration = new FunctionRegistration<>(
new Reverse(), "reverse").type(FunctionType.of(Reverse.class));
SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
catalog.register(upperCaseRegistration);
catalog.register(reverseRegistration);
Function<Flux<String>, Flux<String>> lookedUpFunction = catalog
.lookup("uppercase|reverse");
assertThat(lookedUpFunction).isNotNull();
assertThat(lookedUpFunction.apply(Flux.just("star")).blockFirst())
.isEqualTo("RATS");
}
示例7
@Test
public void testFunctionCompositionImplicit() {
FunctionRegistration<Words> wordsRegistration = new FunctionRegistration<>(
new Words(), "words").type(FunctionType.of(Words.class));
FunctionRegistration<Reverse> reverseRegistration = new FunctionRegistration<>(
new Reverse(), "reverse").type(FunctionType.of(Reverse.class));
FunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
catalog.register(wordsRegistration);
catalog.register(reverseRegistration);
// There's only one function, we should be able to leave that blank
Supplier<String> lookedUpFunction = catalog.lookup("words|");
assertThat(lookedUpFunction).isNotNull();
assertThat(lookedUpFunction.get()).isEqualTo("olleh");
}
示例8
@Test
@Disabled
public void testFunctionCompletelyImplicitComposition() {
FunctionRegistration<Words> wordsRegistration = new FunctionRegistration<>(
new Words(), "words").type(FunctionType.of(Words.class));
FunctionRegistration<Reverse> reverseRegistration = new FunctionRegistration<>(
new Reverse(), "reverse").type(FunctionType.of(Reverse.class));
SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
catalog.register(wordsRegistration);
catalog.register(reverseRegistration);
// There's only one function, we should be able to leave that blank
Supplier<Flux<String>> lookedUpFunction = catalog.lookup("|");
assertThat(lookedUpFunction).isNotNull();
assertThat(lookedUpFunction.get().blockFirst()).isEqualTo("olleh");
}
示例9
@Test
public void testFunctionCompositionWithMessages() {
FunctionRegistration<UpperCaseMessage> upperCaseRegistration = new FunctionRegistration<>(
new UpperCaseMessage(), "uppercase")
.type(FunctionType.of(UpperCaseMessage.class));
FunctionRegistration<ReverseMessage> reverseRegistration = new FunctionRegistration<>(
new ReverseMessage(), "reverse")
.type(FunctionType.of(ReverseMessage.class));
SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
catalog.register(upperCaseRegistration);
catalog.register(reverseRegistration);
Function<Flux<Message<String>>, Flux<Message<String>>> lookedUpFunction = catalog
.lookup("uppercase|reverse");
assertThat(lookedUpFunction).isNotNull();
assertThat(lookedUpFunction
.apply(Flux.just(MessageBuilder.withPayload("star").build())).blockFirst()
.getPayload()).isEqualTo("RATS");
}
示例10
@Test
public void testFunctionCompositionMixedMessages() {
FunctionRegistration<UpperCaseMessage> upperCaseRegistration = new FunctionRegistration<>(
new UpperCaseMessage(), "uppercase")
.type(FunctionType.of(UpperCaseMessage.class));
FunctionRegistration<Reverse> reverseRegistration = new FunctionRegistration<>(
new Reverse(), "reverse").type(FunctionType.of(Reverse.class));
SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
catalog.register(upperCaseRegistration);
catalog.register(reverseRegistration);
Function<Message<String>, String> lookedUpFunction = catalog
.lookup("uppercase|reverse");
assertThat(lookedUpFunction).isNotNull();
String result = lookedUpFunction.apply(MessageBuilder.withPayload("star").setHeader("foo", "bar").build());
assertThat(result).isEqualTo("RATS");
}
示例11
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testReactiveFunctionMessages() {
FunctionRegistration<ReactiveFunction> registration = new FunctionRegistration<>(new ReactiveFunction(), "reactive")
.type(FunctionType.of(ReactiveFunction.class));
SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
catalog.register(registration);
Function lookedUpFunction = catalog.lookup("reactive");
assertThat(lookedUpFunction).isNotNull();
Flux<List<String>> result = (Flux<List<String>>) lookedUpFunction
.apply(Flux.just(MessageBuilder
.withPayload("[{\"name\":\"item1\"},{\"name\":\"item2\"}]")
.setHeader(MessageHeaders.CONTENT_TYPE, "application/json")
.build()
));
Assertions.assertIterableEquals(result.blockFirst(), Arrays.asList("item1", "item2"));
}
示例12
/**
* Will transform all discovered Kotlin's Function lambdas to java
* Supplier, Function and Consumer, retaining the original Kotlin type
* characteristics.
*
* @return the bean factory post processor
*/
@Bean
public BeanFactoryPostProcessor kotlinToFunctionTransformer() {
return new BeanFactoryPostProcessor() {
@Override
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName);
ResolvableType rt = beanDefinition.getResolvableType();
if (rt.getType().getTypeName().startsWith("kotlin.jvm.functions.Function")) {
RootBeanDefinition cbd = new RootBeanDefinition(KotlinFunctionWrapper.class);
ConstructorArgumentValues ca = new ConstructorArgumentValues();
ca.addGenericArgumentValue(beanDefinition);
cbd.setConstructorArgumentValues(ca);
((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(beanDefinitionName + FunctionRegistration.REGISTRATION_NAME_SUFFIX, cbd);
}
}
}
};
}
示例13
@Override
public FunctionRegistration getObject() throws Exception {
String name = this.name.endsWith(FunctionRegistration.REGISTRATION_NAME_SUFFIX)
? this.name.replace(FunctionRegistration.REGISTRATION_NAME_SUFFIX, "")
: this.name;
Type functionType = FunctionContextUtils.findType(name, this.beanFactory);
FunctionRegistration<?> registration = new FunctionRegistration<>(this, name);
Type[] types = ((ParameterizedType) functionType).getActualTypeArguments();
if (functionType.getTypeName().contains("Function0")) {
functionType = ResolvableType.forClassWithGenerics(Supplier.class, ResolvableType.forType(types[0]))
.getType();
}
else if (functionType.getTypeName().contains("Function1")) {
functionType = ResolvableType.forClassWithGenerics(Function.class, ResolvableType.forType(types[0]),
ResolvableType.forType(types[1])).getType();
}
else {
throw new UnsupportedOperationException("Multi argument Kotlin functions are not currently supported");
}
registration = registration.type(functionType);
return registration;
}
示例14
@Bean
@ConditionalOnProperty(prefix = "spring.cloud.function.web.export.source", name = "url")
public FunctionRegistration<Supplier<Flux<?>>> origin(WebClient.Builder builder) {
HttpSupplier supplier = new HttpSupplier(builder.build(), this.props);
FunctionRegistration<Supplier<Flux<?>>> registration = new FunctionRegistration<>(supplier);
FunctionType type = FunctionType.supplier(this.props.getSource().getType()).wrap(Flux.class);
if (this.props.getSource().isIncludeHeaders()) {
type = type.message();
}
registration = registration.type(type);
return registration;
}
示例15
@Override
public void initialize(GenericApplicationContext applicationContext) {
applicationContext.registerBean("uppercase", FunctionRegistration.class,
() -> new FunctionRegistration<>(uppercase())
.type(FunctionType.from(String.class).to(String.class)));
applicationContext.registerBean("reverse", FunctionRegistration.class,
() -> new FunctionRegistration<>(reverse())
.type(FunctionType.from(String.class).to(String.class)));
applicationContext.registerBean("lowercase", FunctionRegistration.class,
() -> new FunctionRegistration<>(lowercase())
.type(FunctionType.from(String.class).to(String.class)));
applicationContext.registerBean("supplier", FunctionRegistration.class,
() -> new FunctionRegistration<>(supplier())
.type(FunctionType.supplier(String.class)));
}
示例16
@Override
public FunctionRegistration<?> getRegistration(Object function) {
String functionName = function == null ? null
: this.lookupFunctionName(function);
if (StringUtils.hasText(functionName)) {
FunctionRegistration<?> registration = new FunctionRegistration<Object>(
function, functionName);
FunctionType functionType = this.findType(registration, functionName);
return registration.type(functionType.getType());
}
return null;
}
示例17
private FunctionRegistration<?> find(String name, boolean supplierFound) {
Object result = this.functions.get(name);
if (result == null && !StringUtils.hasText(name)) {
if (supplierFound && this.getFunctionNames().size() == 1) {
result = this.functions.get(this.getFunctionNames().iterator().next());
}
else if (!supplierFound && this.getSupplierNames().size() == 1) {
result = this.functions.get(this.getSupplierNames().iterator().next());
}
}
return getRegistration(result);
}
示例18
@Override
Type discoverFunctionType(Object function, String... names) {
if (function instanceof RoutingFunction) {
return FunctionType.of(FunctionContextUtils.findType(applicationContext.getBeanFactory(), names)).getType();
}
else if (function instanceof FunctionRegistration) {
return ((FunctionRegistration) function).getType().getType();
}
boolean beanDefinitionExists = false;
for (int i = 0; i < names.length && !beanDefinitionExists; i++) {
beanDefinitionExists = this.applicationContext.getBeanFactory().containsBeanDefinition(names[i]);
if (this.applicationContext.containsBean("&" + names[i])) {
Class<?> objectType = this.applicationContext.getBean("&" + names[i], FactoryBean.class)
.getObjectType();
return FunctionTypeUtils.discoverFunctionTypeFromClass(objectType);
}
}
if (!beanDefinitionExists) {
logger.info("BeanDefinition for function name(s) '" + Arrays.asList(names) +
"' can not be located. FunctionType will be based on " + function.getClass());
}
Type type = FunctionTypeUtils.discoverFunctionTypeFromClass(function.getClass());
if (beanDefinitionExists) {
Type t = FunctionTypeUtils.getImmediateGenericType(type, 0);
if (t == null || t == Object.class) {
type = FunctionType.of(FunctionContextUtils.findType(this.applicationContext.getBeanFactory(), names)).getType();
}
}
return type;
}
示例19
private static Type extractReactiveType(Type type) {
if (type instanceof ParameterizedType && FunctionRegistration.class.isAssignableFrom(((Class<?>) ((ParameterizedType) type).getRawType()))) {
type = getImmediateGenericType(type, 0);
if (type instanceof ParameterizedType) {
type = getImmediateGenericType(type, 0);
}
}
return type;
}
示例20
FunctionTypeConversionHelper(FunctionRegistration<?> functionRegistration, ConversionService conversionService,
MessageConverter messageConverter) {
this.conversionService = conversionService;
this.messageConverter = messageConverter;
this.functionRegistration = functionRegistration;
if ((this.functionRegistration.getType().getType()) instanceof ParameterizedType) {
this.functionArgumentTypes = ((ParameterizedType) this.functionRegistration.getType().getType())
.getActualTypeArguments();
}
else {
this.functionArgumentTypes = new Type[] { this.functionRegistration.getType().getInputType() };
}
}
示例21
default boolean isMessage(Object function) {
FunctionRegistration<?> registration = getRegistration(function);
if (registration != null && registration.getTarget() instanceof FunctionInvocationWrapper
&& ((FunctionInvocationWrapper) registration.getTarget()).getTarget() instanceof RoutingFunction) {
// we always want to give routing function as much information as possible
return true;
}
return registration == null ? false : registration.getType().isMessage();
}
示例22
@SuppressWarnings("unchecked")
@Override
public <T> void register(FunctionRegistration<T> registration) {
this.registrationsByFunction.put(registration.getTarget(), (FunctionRegistration<Object>) registration);
for (String name : registration.getNames()) {
this.registrationsByName.put(name, (FunctionRegistration<Object>) registration);
}
}
示例23
@Override
public FunctionRegistration<?> getRegistration(Object function) {
FunctionRegistration<?> registration = this.registrationsByFunction.get(function);
// need to do this due to the deployer not wrapping the actual target into FunctionInvocationWrapper
// hence the lookup would need to be made by the actual target
if (registration == null && function instanceof FunctionInvocationWrapper) {
function = ((FunctionInvocationWrapper) function).target;
}
return this.registrationsByFunction.get(function);
}
示例24
@Test
public void testFunctionCompositionExplicit() {
FunctionRegistration<Words> wordsRegistration = new FunctionRegistration<>(
new Words(), "words").type(FunctionType.of(Words.class));
FunctionRegistration<Reverse> reverseRegistration = new FunctionRegistration<>(
new Reverse(), "reverse").type(FunctionType.of(Reverse.class));
SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
catalog.register(wordsRegistration);
catalog.register(reverseRegistration);
Supplier<String> lookedUpFunction = catalog.lookup("words|reverse");
assertThat(lookedUpFunction).isNotNull();
assertThat(lookedUpFunction.get()).isEqualTo("olleh");
}
示例25
@Test
public void lookUps() {
create(SimpleConfiguration.class);
assertThat(this.context.getBean("function"))
.isInstanceOf(FunctionRegistration.class);
assertThat((Function<?, ?>) this.catalog.lookup(Function.class, "function"))
.isInstanceOf(Function.class);
}
示例26
@Test
public void properties() {
create(PropertiesConfiguration.class, "app.greeting=hello");
assertThat(this.context.getBean("function"))
.isInstanceOf(FunctionRegistration.class);
@SuppressWarnings("unchecked")
Function<Flux<String>, Flux<String>> function = (Function<Flux<String>, Flux<String>>) this.catalog
.lookup(Function.class, "function");
assertThat(function).isInstanceOf(Function.class);
assertThat(function.apply(Flux.just("foo")).blockFirst()).isEqualTo("hello foo");
}
示例27
@Test
public void value() {
create(ValueConfiguration.class, "app.greeting=hello");
assertThat(this.context.getBean("function"))
.isInstanceOf(FunctionRegistration.class);
@SuppressWarnings("unchecked")
Function<Flux<String>, Flux<String>> function = (Function<Flux<String>, Flux<String>>) this.catalog
.lookup(Function.class, "function");
assertThat(function).isInstanceOf(Function.class);
assertThat(function.apply(Flux.just("foo")).blockFirst()).isEqualTo("hello foo");
}
示例28
@Test
@Disabled
public void compose() {
create(SimpleConfiguration.class);
assertThat(this.context.getBean("function"))
.isInstanceOf(FunctionRegistration.class);
@SuppressWarnings("unchecked")
Supplier<Flux<String>> supplier = (Supplier<Flux<String>>) this.catalog
.lookup(Supplier.class, "supplier|function");
assertThat(supplier).isInstanceOf(Supplier.class);
assertThat(supplier.get().blockFirst()).isEqualTo("HELLO");
// TODO: support for function composition
}
示例29
@Test
public void missingType() {
Assertions.assertThrows(BeanCreationException.class, () -> {
create(MissingTypeConfiguration.class);
assertThat(this.context.getBean("function"))
.isInstanceOf(FunctionRegistration.class);
assertThat((Function<?, ?>) this.catalog.lookup(Function.class, "function"))
.isInstanceOf(Function.class);
// TODO: support for type inference from functional bean registrations
});
}
示例30
@Test
public void dependencyInjection() {
create(DependencyInjectionConfiguration.class);
assertThat(this.context.getBean("foos")).isInstanceOf(FunctionRegistration.class);
assertThat((Function<?, ?>) this.catalog.lookup(Function.class, "foos"))
.isInstanceOf(Function.class);
assertThat(
this.inspector.getInputType(this.catalog.lookup(Function.class, "foos")))
.isEqualTo(String.class);
}