简体   繁体   中英

Autowire Map with custom class and use aliases to get the correct object reference

I have the following code:

public interface PolicyDetailsService {
    public void display();
}

Following are the implementations

@Service("PolicyDetailsServiceImpl")
public class PolicyDetailsServiceImpl implements PolicyDetailsService {

    @Override
    public void display() {
        System.out.println("PolicyDetailsServiceImpl displayed");
    }

}

public class PreneedPolicyDetailsServiceImpl implements PolicyDetailsService {

    @Override
    public void display() {
        System.out.println("PreneedPolicyDetailsServiceImpl displayed");
        
    }

}

public class PreneedTrustPolicyDetailsServiceImpl implements PolicyDetailsService {

    @Override
    public void display() {
        System.out.println("PreneedTrustPolicyDetailsServiceImpl displayed");
        
    }

}

I am creating the objects by creating beans like the following,

@Bean(name = { "AGENCY-PLI", "AGENCY-PMM" })
public PolicyDetailsServiceImpl getPolicyDetailsServiceImpl(
        @Autowired PolicyDetailsServiceImpl policyDetailsServiceImpl) {

    return policyDetailsServiceImpl;
}

@Bean(name = { "AFS-AFS", "AFS-PMM" })
public PreneedPolicyDetailsServiceImpl getPreneedPolicyDetailsServiceImpl() {
    return new PreneedPolicyDetailsServiceImpl();
}

@Bean({ "AFS-PMT" })
public PreneedTrustPolicyDetailsServiceImpl getPreneedTrustPolicyDetailsServiceImpl() {
    return new PreneedTrustPolicyDetailsServiceImpl();
}

The controller where i am using the services,

@Autowired
Map<String, PolicyDetailsService> policyDetails;

@GetMapping("/display/{displayName}")
public String display(@PathVariable String displayName) {
    
    try {
        policyDetails.get(displayName).display();
    }catch(Exception e) {
        e.printStackTrace();
    }
    
    return "Display Succesfull";
}

What i want to acheive: If I pass either "AGENCY-PLI" or "AGENCY-PMM" in the REST service call, the map should return PolicyDetailsServiceImpl object. It is currently working for "AGENCY-PLI". On passing "AGENCY-PMM" i am getting NullPointerException as the map is not returing any object. My understanding is, the "AGENCY-PLI" is acting as a primary name and the other names are aliases. So if i used it like the following,

@Autowired
@Qualifier("AGENCY-PMM")
private PolicyDetailsService policyDetailsService;

I would get the correct object reference. So, my question: Is there a way i can get the object from the map on passing aliases.

Actually I think the solution can be done without holding a map. Here is a possible solution you can try.

@Autowired
ApplicationContext applicationContext;

@GetMapping("/display/{displayName}")
public String display(@PathVariable String displayName) {
    
    try {
        PolicyDetailsService service = applicationContext.getBean(displayName, PolicyDetailsService.class);
        service.display();
    }catch(Exception e) {
        e.printStackTrace();
    }
    
    return "Display Succesfull";
}

In addition, I am wondering why you create a PolicyDetailsServiceImpl bean using @Service and another using @Bean , is it a typo? In case you would like to create one Singleton, I think you better remove the @Service in PolicyDetailsServiceImpl and add the name in @Bean(name=xxx)

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