Krishna
Krishna

Reputation: 3177

Bean injection failing in Library

I created one library, in which i created some beans. Below is the file where i am creating some beans:

@Configuration
public class StorageBindings {

  @Value("${storageAccountName}")
  private String storageAccountName;

  @Value("${storageAccountKey}")
  private String storageAccountKey;


  @Bean(name = "cloudBlobClient")
  public CloudBlobClient getCloudBlobClientUsingCredentials() throws URISyntaxException {
     return new CloudBlobClient();
  }


  @Bean(name = "storageCredentialsToken")

  public StorageCredentialsToken getStorageCredentialsToken() throws IOException {
     return new StorageCredentialsToken();
  }

  @Bean(name = "msiTokenGenerator")
  public MSITokenGenerator getMSITokenGenerator() {
    return new MSITokenGenerator();
  }
}

Then i created the class, which i use as entry point to do further operations

public class StorageClient {

  @Autowired
  private CloudBlobClient cloudBlobClient;

  @Autowired
  private MSITokenGenerator msiTokenGenerator;

  @Value("${storageAccountName}")
  private String storageAccountName;

  @Value("${storageAccountKey}")
  private String storageAccountKey;
}

I created the jar with above files and include it in our main project, where i created the bean of StorageClient as below:

@Bean(name = {"storageClient"})
    public StorageClient getStorageClient() {
        LOG.debug("I am inside storage class");
        StorageClient ac = null;
        try {
            ac = new StorageClient();
            return ac;
    }

But after execution i found that no injection in StorageClient instance ac for below variables and not even environment property getting reflected and all of them are null:

   //beans NOT Injecting 
   ac.cloudBlobClient=null;
   ac.msiTokenGenerator=null;

//env variables
   ac.storageAccountName=null;
   ac.storageAccountKey=null;

Am i missing something, as i am getting null. Sequence of instantiation of beans are ok. I checked. So first beans of StorageBindings are getting created.

Upvotes: 1

Views: 525

Answers (2)

Wojtek Mlodzianowski
Wojtek Mlodzianowski

Reputation: 398

If you are creating object inside @Bean annotated method autowiring doesn't inject beans there - you simply are creating it by yourself. So you have to @Autowire it ie on fields in your Configuration class and set with setter/constructor. Ie:

@Autowired
private CloudBlobClient cloudBlobClient;

@Autowired
private MSITokenGenerator msiTokenGenerator;

@Bean(name = {"storageClient"})
public StorageClient getStorageClient() {
       LOG.debug("I am inside storage class");
       StorageClient ac = null;
       try {
              ac = new StorageClient();
              ac.setCloudBlobClient(cloudBlobClient);
              ac.setMsiTokenGenerator(msiTokenGenerator);
              return ac;
       }
}

Upvotes: 2

Francesc Recio
Francesc Recio

Reputation: 2235

When you do this:

ac = new StorageClient();

you lose the context of spring, because you are creating a new instance out of that context. The beans inside CloudBlobClient,MSITokenGenerator and variables storageAccountName,storageAccountKey, they don't get injected.

You can annotate StorageClient with @Component.

So since you pack it as jar, in your main project you have to make sure that the @ComponentScan includes the path where StorageClient is.

Then you can do:

@Autowired
private StorageClient storageClient;

in your main project.

Upvotes: 3

Related Questions