Search code examples
javaspringspring-bootabstract-classautowired

Spring Boot - Autowiring null inside abstract class


I have below classes.

public interface Operation
public abstract class AbstractOperation  implements Operation
public class Operation extends AbstractOperation

Class Operation

public interface Operation {
     GenericClientResponse validateCustomerId();

Class AbstractOperation

public abstract class AbstractOperation  implements Operation {

    protected GenericClientRequest buildClientValidationRequest() {
        return new GenericClientRequest();
    }

In Operation class there are properties autowired.

public class Operation extends AbstractOperation {
    @Autowired
    UserAccountsRepository userAccountsRepository; // not autowiring
    @Autowired
    WebClient.Builder webClientBuilder; // not autowiring

But none of these properties are autowired. They are null at run time. But if i autowire these in my service class autowiring is successfully done.

    @Service
    @Transactional
    public class TransactionServiceImpl implements TransactionService {

          @Autowired
          UserAccountsRepository userAccountsRepository; // Autowires successfully.

Please find repository class below.

public interface UserAccountsRepository extends 
             JpaRepository<UserAccountsEntity, Integer> {

    @Query("SELECT account FROM UserAccountsEntity account where 
                 account.accountNo = :acc")
    UserAccountsEntity getAccountByAccNo(@Param("acc") String userId);

In my code i keep a map of Operation classes and get related operation class according to a key.

 operationMap.put("test_op1", new Operation());
 operationMap.put("test_op2", new Operation2());

Then i call this to get correct operation

Optional.ofNullable(operationMap.get("test_op1"));

Now i undestands that creating new instance is causing null autowiring. How i get new object without new key word?


Solution

  • You're probably instantiating Operation with new as follows:

    Operation operation = new Operation(...);
    

    This is making your Operation instance non-Spring managed. Hence, since Spring doesn't know about your instance, it cannot autowire your dependencies.

    If you do like:

    @Component
    public class Operation {
    ...
    }
    

    you will get your dependencies autowired correctly. If you really need to instantiate Operation yourself and keep the autowired dependencies, you'll need to go for Configurable. See a couple of references: