Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

Creating Spring context

Code Block
languagejava
public class InitAPIImpl implements InitAPI {

 @Override
 public void init(Vertx vertx, Context context, Handler<AsyncResult<Boolean>> handler) {
    vertx.executeBlocking(
      future -> {
        SpringContextUtil.init(vertx, context, ApplicationConfig.class);
        future.complete();
      },
      result -> {
        if (result.succeeded()) {
          handler.handle(Future.succeededFuture(true));
        } else {
          handler.handle(Future.failedFuture(result.cause()));
        }
      });
  }
}


We implemented class SpringContextUtil to use Spring dependency injection in Vert.x applications.

SpringContextUtil#init method initializes Spring context and adds it to Vertx Context object.

Accessing Spring context from endpoint classes

Code Block
languagejava
public class EholdingsProxyTypesImpl implements EholdingsProxyTypes {

 private final Logger logger = LoggerFactory.getLogger(EholdingsProxyTypesImpl.class);

 @Autowired
 private RMAPIConfigurationService configurationService;
 @Autowired
 private ProxyConverter converter;
 @Autowired
 private HeaderValidator headerValidator;

  @SuppressWarnings("squid:S1172")
  public EholdingsProxyTypesImpl(Vertx vertx, String tenantId) {
    SpringContextUtil.autowireDependencies(this, vertxVertx.getOrCreateContextcurrentContext());

 }


SpringContextUtil#autowireDependencies method gets Spring context from Vertx context and uses it to inject beans into EholdingsProxyTypesImpl.

RestVerticle will call constructor with parameters (Vertx vertx, String tenantId) default constructor through reflection.

@SuppressWarnings("squid:S1172") annotation is needed because Sonar can't see reflection calls and considers tenantId parameter to be unnecessary.

Declaring Spring configuration

SpringContextUtil#init uses Spring configuration class. 

...


vertx and expirationTime parameters will be automatically injected by Spring, expirationTime will be set to the value of  "configuration.cache.expire" property from application.properties file.

Benefits of using Spring DI

1) Spring allows to inject properties by using @Value annotation, without this we need to manually read file and share it across application.

...

Expand
private RMAPIConfigurationService configurationService;
private PackagesConverter converter;
private HeaderValidator headerValidator;
private PackageParametersValidator packageParametersValidator;
private PackagePutBodyValidator packagePutBodyValidator;
private CustomPackagePutBodyValidator customPackagePutBodyValidator;
private PackagesPostBodyValidator packagesPostBodyValidator;
private TitleParametersValidator titleParametersValidator;
private ResourcesConverter resourceConverter;
private IdParser idParser;

public EholdingsPackagesImpl() {
this(
new RMAPIConfigurationServiceCache(
new RMAPIConfigurationServiceImpl(new ConfigurationClientProvider())),
new HeaderValidator(),
new PackageParametersValidator(),
new PackagePutBodyValidator(),
new CustomPackagePutBodyValidator(),
new PackagesPostBodyValidator(),
new PackagesConverter(),
new TitleParametersValidator(),
new ResourcesConverter(),
new IdParser());
}
// Surpressed warning on number parameters greater than 7 for constructor
@SuppressWarnings("squid:S00107")
public EholdingsPackagesImpl(RMAPIConfigurationService configurationService,
HeaderValidator headerValidator,
PackageParametersValidator packageParametersValidator,
PackagePutBodyValidator packagePutBodyValidator,
CustomPackagePutBodyValidator customPackagePutBodyValidator,
PackagesPostBodyValidator packagesPostBodyValidator,
PackagesConverter converter,
TitleParametersValidator titleParametersValidator,
ResourcesConverter resourceConverter,
IdParser idParser) {
this.configurationService = configurationService;
this.headerValidator = headerValidator;
this.packageParametersValidator = packageParametersValidator;
this.packagesPostBodyValidator = packagesPostBodyValidator;
this.converter = converter;
this.packagePutBodyValidator = packagePutBodyValidator;
this.customPackagePutBodyValidator = customPackagePutBodyValidator;
this.titleParametersValidator = titleParametersValidator;
this.resourceConverter = resourceConverter;
this.idParser = idParser;
}


With Spring:

Expand
@Autowired
private RMAPIConfigurationService configurationService;
@Autowired
private PackagesConverter converter;
@Autowired
private HeaderValidator headerValidator;
@Autowired
private PackageParametersValidator packageParametersValidator;
@Autowired
private PackagePutBodyValidator packagePutBodyValidator;
@Autowired
private CustomPackagePutBodyValidator customPackagePutBodyValidator;
@Autowired
private PackagesPostBodyValidator packagesPostBodyValidator;
@Autowired
private TitleParametersValidator titleParametersValidator;
@Autowired
private ResourcesConverter resourceConverter;
@Autowired
private IdParser idParser;
@SuppressWarnings("squid:S1172")

public EholdingsPackagesImpl(Vertx vertx, String tenantId) {
SpringContextUtil.autowireDependencies(this, vertxVertx.getOrCreateContextcurrentContext());
}


4) It resolves circular dependencies between objects.

...

6) Objects are created once instead of being created on each request.

Drawbacks of using Spring DI

1) It introduces another framework that developers need to know.



2) Creating objects at the point when they are used can be easier. With DI it can be more difficult to know when object is constructed and how it is injected.Presentation on dependency injection Spring_DI.pptx