derjust / spring-data-dynamodb

This module deals with enhanced support for a data access layer built on AWS DynamoDB.
https://derjust.github.io/spring-data-dynamodb/
Apache License 2.0
403 stars 141 forks source link

Setup Repositories programatically #246

Open vermapratyush opened 5 years ago

vermapratyush commented 5 years ago

I am trying to use a library which provide CRUD operations over a dynamo table using spring-data-dynamodb library. The library expects that SpringApplication is annotated with @EnableDynamoDBRepositories so that spring can search for all repositories and wire them up.

However, I do not want to use annotations in my application, I want to programatically scan for the repositories and auto-wire them where necessary.

What I currently have is

val context = new AnnotationConfigApplicationContext()
context.register(classOf[DDBClient], classOf[SampleRepository])
context.scan("com.test.ddb.repository")
context.refresh()

com.test.ddb.repository contains the interface SampleRepository which extends CrudRepository.

In the above code, I know that DDBClient is able to create the beans AmazonDynamoDB, AWSCredentialsProvider, DynamoDBMapperConfig, DynamoDBMappingContext.

However, spring reports that it is unable to instantiate the bean SampleRepository, with the following log.

All those information are logged by

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.test.ddb.repository.SampleRepository]: Specified class is an interface
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:70)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1262)
    ... 33 more
derjust commented 5 years ago

May I ask what you underlying thing is you are trying to achieve? There is a fair amount of filters & exclusion lists that let you define verify precise what is scanned and what not.

On a similar note - is using the (classic Spring) XML a way forward? So you would build your ApplicationContext via new ClassPathXmlApplicationContext()

Proposing all this as hooking into all of this via pure code will be a hell of a ride - mainly because spring-data-dynamodb is a 'plugin' for spring-data itself registered via a bunch of hooks - all those must be called manually & the necessary initialization must be done manually. On top, all of those implemented interfaces & call backs are not 'public API' and change fairly often from the spring-data side of things (even between patch levels - at least in the past)

vermapratyush commented 5 years ago

I have a dao library (written in java) which uses spring-boot + spring-data + dynamodb, it contains logic related to DAO (like partitioning/secondary indexes/hash keys/etc).

I need to use the same java library in a spark (scala) application. So, I suppose I have 2 options.

  1. As part of the spark application, bring up the spring application and auto-wire the Repository in scala code or get the beans via springApplication.getBean. I have got this working.
  2. Exclude spring dependencies and wire up the dependencies manually.

With option 1, spring-boot brings in a lot of overhead and dependencies, the spark application startup would be slow and bloat up the fat jar (spark application is far jar). I was hoping with option 2, I would be able to skip annotation processing and also exclude unnecessary dependencies from the final jar.

But you are right, I didn't consider the impact of changes in 'non-public API' breaking the manual wiring of dependencies and overhead of maintaining the hooks between spring-data-dynamodb and spring-data. Given this, I guess option 1 seems like a better choice.