4

This is a kind of "what is @Service annotation?" question, but with another approach. Because, I am not sure what is going on here:

I have a controller class:

@Controller
public class GreetingController {
    @Autowired
    SomeBean someBean;

    @MessageMapping("/msg")
    public String msg() {
        someBean.handleMsg();
        return "";
    }
}

From within someBean.handleMsg I try to send a response to a destination. Some thing like this:

public class SomeBean {
    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    public handleMsg() {
        messagingTemplate.convertAndSend("/topic/someTopic", "Response");
    }
}

There are two versions of configuration.

  1. SomeBean is configured in .xml:

Like:

< bean id="someBean" class="package.SomeBean"></bean>
  1. SomeBean is annotated as service (in the first one it does not have):

Like:

@Service
public class SomeBean{...}
  • Please note that in these two cases there is not any problem about injections etc. In both cases the client is successfully subscribed, sent message, and message is handled.

The only difference is:

  • When SomeBean has @Service annotation, it successfully responses to the client, but when it does NOT have, the client does not receive the response message, although there is not any exception.

Here is the question:

  • What actually does @Service in this case? Could someone please explain what is going on here?
Mert Mertce
  • 1,614
  • 3
  • 21
  • 32
  • Doesn't the file service.java of package org.springframework.stereotype indicate why service annotations are for? I see that it does. – We are Borg Mar 31 '15 at 12:04
  • I have trouble believing your description of events; failure to send the message, for a number of reasons, would generate a corresponding exception. Something else is different. You might consider setting a breakpoint in the service method and stepping through in each case. – chrylis -cautiouslyoptimistic- Mar 31 '15 at 17:20
  • @chrylis, maybe you're right, I also wonder why I didn't get any exception but just silently the client receives nothing when there is not Service annotation. – Mert Mertce Mar 31 '15 at 17:37

2 Answers2

2

From a technical point of view there is little difference between @Service and xml based configuration. Both methods are used for declaring Java classes as Spring beans which are managed and used for dependency injection inside a Spring based application.

Main difference is that a class annotated with @Service is a candicate for autodetection during classpath scanning. With annotation driven dependency injection you don't need to declare every Java class as a Spring bean inside your xml configuration.

That is what the javadoc says:

Indicates that an annotated class is a "Service", originally defined by Domain-Driven Design (Evans, 2003) as "an operation offered as an interface that stands alone in the model, with no encapsulated state."

May also indicate that a class is a "Business Service Facade" (in the Core J2EE patterns sense), or something similar. This annotation is a general-purpose stereotype and individual teams may narrow their semantics and use as appropriate.

This annotation serves as a specialization of @Component, allowing for implementation classes to be autodetected through classpath scanning.

ksokol
  • 8,035
  • 3
  • 43
  • 56
  • Thank you ksokol. So could you tell that in my question the behaviour in 2 cases should be the same? I do have read this javadoc but I couldn't explain my case, so I though I was missing some thing. – Mert Mertce Mar 31 '15 at 17:35
  • @mert-mertce Yes you're right. The behaviour is exactly the same. – ksokol Mar 31 '15 at 18:26
2

@Service: This tells Spring it is a Service class, where you might have @Transactional etc Service layer related annotations so Spring treats it as a Service component.

Plus @Service is a specialization of @Component. Assume the bean class name is "CustomerService", since you did not choose XML bean configuration way so you annotated the bean with @Component to indicate it as a Bean. So you can retrieve this bean with :

CustomerService cust = (CustomerService)context.getBean("customerService");

By default, Spring will lower case the first character of the component – from ‘CustomerService’ to ‘customerService’. And you can retrieve this component with name ‘customerService’.

Just like with the @Component annotation, if you use the @Service annotation you can provide it a specific bean name like this :

@Service("myBeanName")
public class CustomerService{

and you can get the bean object by :

CustomerService cust = (CustomerService)context.getBean("myBeanName");
Arun Raaj
  • 1,762
  • 1
  • 21
  • 20