This small library helps with embedding Vert.x inside a Spring Boot or classic Spring application.
Import the library as a dependency in your build tool of choice:
dependencies {
implementation 'org.unbroken-dome.vertx-spring:vertx-spring:0.2.3'
}
Vertx-spring is available from the JCenter repository.
To use Vert.x inside your application, simply put the @EnableVertx
annotation on one of
your @Configuration
classes:
@Configuration
@EnableVertx
public class MyConfiguration {
// Verticle beans will be auto-deployed once Vertx has started up
@Bean
public MyVerticle myVerticle() { return new MyVerticle(); }
}
Auto-configuration for Spring Boot applications is available as well, simply by putting this library on the classpath.
The Vertx
instance is created, started and shut down as part of the Spring
Lifecycle.
Spring beans of type Verticle
will be detected and deployed automatically.
Under the covers, using the @EnableVertx
annotation will import some Spring configurations and ultimately register
a SpringVertx
bean. It serves as the container for a Vertx
instance and adapts it to the Spring lifecycle.
For additional configuration, you can make any of your beans (or @Configuration
classes) implement the
VertxConfigurer
interface. It has one method, configure
, that can be used to set the VertxOptions
or register
verticles for deployment once the Vertx
instance has been started.
@Configuration
@EnableVertx
public class MyConfiguration implements VertxConfigurer {
@Override
public void configure(SpringVertx.Builder builder) {
builder
// Register a custom Verticle for deployment
.verticle(new MyVerticle())
// Modify the VertxOptions
.options(opt -> opt.setClustered(true));
}
}
When multiple VertxConfigurer
beans are present, their ordering can be specified by annotating them with @Order
.
When using Spring Boot, it is also possible to specify most of the VertxOptions
settings via the application
properties (see below).
Vert.x does not separate between creation and startup of a Vertx
instance. Since it is created as a result of the
Spring lifecycle (not on Application context refresh), it is not available when the application context is initialized,
so it cannot be injected into other beans directly.
The recommended way to use Vert.x with this library is to register Verticle
beans (see below for more details).
Verticles will have their lifecycle managed by Vert.x, and will be initialized with the Vert.x
instance with which
they can work.
If you really need to use the Vertx
instance from outside a Verticle, you can have any bean implement the
VertxListener
interface, and it will be notified about the Vertx instance starting and stopping (passing the
Vertx
object as a parameter):
@Component
public class MyVertxComponent implements VertxListener {
@Override
public void vertxStarted(Vertx vertx, VertxOptions options) {
// Work with the Vertx instance
}
}
The events that the listener supports (Vertx started/stopped, verticle deployed/undeployed) are also published as
Spring ApplicationEvent`s, so you can subscribe to them using an `ApplicationListener
:
@Component
public class MyVertxComponent implements ApplicationListener<VertxStartedEvent> {
@Override
public void onApplicationEvent(VertxStartedEvent event) {
Vertx vertx = event.getVertx();
// Work with the Vertx instance
}
}
Verticles are the conventional unit of modularization in Vert.x.
If you add a Spring bean to your application context whose type is Verticle
(or an implementing class), it will be
picked up and deployed automatically once the Vertx
instance has started.
If you do not like this auto-deployment behavior, you can disable it using the deployVerticles
parameter of the
@EnableVertx
annotation (by default it is true
):
@Configuration
@EnableVertx(deployVerticles = false)
public class MyConfiguration {
// This verticle will *not* be deployed automatically
@Bean
public Verticle myVerticle() { return new MyVerticle(); }
}
You can also disable auto-deployment per bean, using the @VerticleDeployment
annotation:
@Configuration
@EnableVertx
public class MyConfiguration {
// This verticle will be deployed automatically...
@Bean
public AutoVerticle autoVerticle() { return new AutoVerticle(); }
// ...but this one will not
@Bean
@VerticleDeployment(false)
public ManualVerticle manualVerticle() { return new ManualVerticle(); }
}
There are several methods to fine-tune the verticle deployment process (which is equivalent of providing a
DeploymentOptions
instance when calling Vertx.deployVerticle()
directly).
First, most of the settings from DeploymentOptions
have a corresponding attribute in the @VerticleDeployment
annotation:
@Configuration
@EnableVertx
public class MyConfiguration {
@Bean
@VerticleDeployment(ha = true, instances = 4)
public Verticle myVerticle() { return new MyVerticle(); }
}
Another approach is to wrap the verticle inside a VerticleRegistrationBean
that contains the verticle as well
as the deployment options (be careful not to make the Verticle itself a @Bean
in this case, or it will be deployed
twice):
@Configuration
@EnableVertx
public class MyConfiguration {
@Bean
public VerticleRegistrationBean myVerticle() {
DeploymentOptions options = new DeploymentOptions()
.setHa(true)
.setInstances(4);
return new VerticleRegistrationBean(new MyVerticle())
.setDeploymentOptions(options);
}
}
The verticle can also be "self-describing" its desired deployment options, by implementing the
DeployableVerticle
interface:
@Component
public class MyVerticle extends AbstractVerticle implements DeployableVerticle {
@Override
public DeploymentOptions getDeploymentOptions() {
return new DeploymentOptions()
.setHa(true)
.setInstances(4);
}
}
The standard Spring mechanisms @Order
and Ordered
are recognized and will be used for ordering
verticle deployment. All verticles with a lower order value are guaranteed to be deployed before
verticles with a higher value, while all verticles with the same value are deployed simultaneously.
Again, there are several ways to specify the order:
-
using the
@Order
annotation on the bean method or a@Component
class -
as a property on the
VerticleRegistrationBean
-
by having the Verticle class itself implement
Ordered
Vert.x core allows the number of verticle instances to be specified in the DeploymentOptions
, for example when
distribution of loads across multiple processor cores is desired. However, this obviously doesn’t work if the
Verticle instance has already been created as a singleton.
To use multiple-instance deployment, declare your verticles either as prototype-scoped (with @Scope("prototype")
),
or use a FactoryBean
that creates prototypes.
@Configuration
public class MyConfiguration {
@Bean
@Scope("prototype")
@VerticleDeployment(instances = 4)
public PrototypeVerticle prototypeVerticle() {
return new PrototypeVerticle();
}
@Bean
@VerticleDeployment(instances = 3)
public SomeVerticleFactoryBean factoryCreatedVerticle() {
return new SomeVerticleFactoryBean();
}
}
For Vert.x to create Verticle instances in a multi-instance deployment, it needs a VerticleFactory
that creates
verticles by name. This library contains a VerticleFactory
implementation that resolves verticle names to prototype
Spring beans from the application context. It is registered with the spring:
prefix by default. You can change the
prefix using the verticleFactoryPrefix
method on SpringVertx.Builder
.
The spring:
prefix can also be used to deploy additional verticles after startup.
If the application context contains a bean of type io.vertx.core.spi.cluster.ClusterManager
, it will be used by
the SpringVertx
instance as the cluster manager. Otherwise, the detection/creation of a suitable ClusterManager
will work as described in the Vert.x core documentation.
When using Spring Boot, Vertx will be auto-configured by having this library on the classpath. Most settings from
VertxOptions
can be configured as properties from any Spring PropertySource
. Most commonly, you can configure
these settings in your application.yml or application.properties:
vertx:
clustered: true
event-bus:
host: localhost
port: 42042
If one of the 4 official Vert.x cluster manager implementations ( Hazelcast, Ignite, Infinispan or Zookeeper) is used, it can be configured automatically by being on the classpath.
If (for whatever reason) more than one of these ClusterManager
implementations is available on the classpath,
one has to be chosen explicitly by setting the vertx.cluster-manager.type
property, e.g.
vertx.cluster-manager.type: hazelcast
If io.vertx:vertx-hazelcast
is on the classpath, a HazelcastClusterManager
bean will be created automatically.
vertx-spring will piggy-back on the Hazelcast auto-configuration that is already offered by Spring Boot. Use either of the following three options:
-
Set the
spring.hazelcast.config
property to the location of a configuration resource; -
create a
com.hazelcast.config.Config
bean in your application context -
create a bean of type
com.hazelcast.core.HazelcastInstance
directly.
The HazelcastInstance
will be picked up and used to create a HazelcastClusterManager
.
If io.vertx:vertx-ignite
is on the classpath, an IgniteClusterManager
bean will be created automatically. It will
be configured from a ignite.xml
resource on the classpath, or the default-ignite.xml
from the library
(as described in the documentation).
If io.vertx:vertx-infinispan
is on the classpath, an InfinispanClusterManager
bean will be created automatically.
It will be configured from a infinispan.xml
resource on the classpath
(as described in the documentation).
If io.vertx:vertx-zookeeper
is on the classpath, a ZookeeperClusterManager
bean will be created automatically.
You can configure your Zookeeper client using environment properties:
vertx.cluster-manager.zookeeper:
hosts: 127.0.0.1
session-timeout: 20000
connect-timeout: 3000
root-path: io.vertx
retry:
initial-sleep-time: 100
interval-times: 10000
max-times: 5
Alternatively, you can set the vertx.cluster-manager.zookeeper.config
property to the location of a JSON
configuration resource, as described in the cluster manager
documentation:
vertx.cluster-manager.zookeeper.config: classpath:zookeeper.json