简体   繁体   中英

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?

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:

I can see a couple of possibilities, based on what you've shared:

  1. The package structure is not correct - if the class Operation isn't in the same package (or a sub-package) as the main class, the component scan may pick your class. Please refer this answer to make sure you've implemented the package structure correctly.

  2. You may be missing a Spring annotation on the class Operation , such as @Component or @Service . Or you may be instantiating the class manually in you code, outside of the Spring application context. Please verify that you're creating the bean properly.

In case you're trying to create the bean manually, you should do it using @Bean in a configuration 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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM