简体   繁体   中英

Service bean not autowired properly in Spring Rest Controller

I have a spring rest application which has a Rest Controller as below

@RestController
public class IngestorController
{
    @Autowired
    private IngestorService ingestorService;

    @RequestMapping( value = "/ingestor/createAndDeploy/{ingestorName}", method = RequestMethod.POST )
    public void createAndDeploy( @PathVariable String ingestorName )
    {
        ingestorService.createAndDeploy( ingestorName );
    }

}

Simlilarly I have a Service Bean as below

@Service
public class IngestorService
{
    @Autowired
    private IngestorCommandBuilder ingestorCommandBuilder;

    private String uri;
    private DeployTemplate deployTemplate;

    public void init() throws URISyntaxException
    {
        deployTemplate = new DeployTemplate( new URI( uri ) );
    }

    @Transactional
    public void createAndDeploy( Ingestor ingestor )
    {
         //.....
     }

}

I have the Spring config as show below

<bean id="ingestorCommandBuilder" class="org.amaze.server.ingestor.IngestorCommandBuilder" />

<bean id="ingestorService" class="org.amaze.server.service.IngestorService" init-method="init">
    <property name="uri" value="http://localhost:15217" />
</bean>

<bean id="ingestorController" class="org.amaze.server.controller.IngestorController"/>

When ever I try to start the application context the application context starts and it hits the init method in the IngestorService, deployTemplate object also initilized for the service bean.

But this bean is not autowired for the IngestorController. When I hit the rest endpoint from postman, the service bean has deployTemplate property as null.. The object that is assigned to the ingestorService variable in the Controller is a different object not the one which was called for the init method...

I tried making the service bean singleton (Even if the default scope is singleton) but dint work...

I am not able to find out the mistake I am doing.. Any suggestions appreciated...

If you use annotation-based configuration, you mostly dont need to describe all your beans in application context xml file. Annotations are all you need to autowire service.

To define your init method properly, use @PostConstruct annotation. Properties can be easily moved to externat .properties file and injected to your code with @Value annotation.

Alternatively, use @Qualifier with @Autowired .

First ensure that you have:

<context:annotation-config />

In your Spring config. Now you have severael alternatives:

<context:component-scan base-package="your.package.com" />

to scan for components, or

<!-- autowiring byName, bean name should be same as the property name annotate your ingestorservice with @Service("ingestorServiceByName") -->
<bean name="ingestorServiceByName" class="your.package.com.IngestorService" autowire="byName" />

<!-- autowiring byType, tif there are more bean of the same "general" type, this will not work and you will have to use qualifier or mark one bean as @Primary  -->
<bean name="ingestorServiceByType" class="your.package.com.IngestorService" autowire="byType" />

<!-- autowiring by constructor is similar to type, but the DI will be done by constructor -->
<bean name="ingestorServiceConstructor" class="your.package.com.IngestorService" autowire="constructor" />

Please include your full Spring configuration to make it easier to analyze your problem.

When you are using Annotation based DI, you need not define the beans in XML.

@PostConstruct can be used to replace your init-method of xml config.

Just use

    <context:component-scan base-package="..."/> <mvc:annotation-driven/>

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