how to use #Service annotation in Spring MVC to create the bean of Service layer - spring

Can someone tell how to get the bean of service layer in spring MVC. One way to get the bean of service layer is by using #Service annotation but how to do that, I don't know.
Controller:
#Controller
public class ConfigureApplicationController {
#RequestMapping(value="/ConfigureApplication.html", method=RequestMethod.GET)
public ModelAndView getListOfAllConfigureApplication(){
AppConfigureServiceImpl getService=new AppConfigureServiceImpl();
ArrayList<ConfigureApplication> results =getService.getListOfAllAppConfigure();
ModelAndView model=new ModelAndView("ConfigureApplication");
model.addObject("results",results);
return model;
}
and serviceImpl is:
#Service("appConfigureServiceImpl")
public class AppConfigureServiceImpl implements AppConfigureService {
public ArrayList<ConfigureApplication> getListOfAllAppConfigure(){
#SuppressWarnings("resource")
ApplicationContext ctx=new ClassPathXmlApplicationContext("spring-dispatcher-servlet.xml");
AppConfigureDAOImpl getAll=ctx.getBean("appConfigureDAOImpl", AppConfigureDAOImpl.class);
ArrayList<ConfigureApplication> results =getAll.getList();
return results;
}
In this i have made the object of AppConfigureServiceImpl (in service layer)then i invoke the method but by doing so i am not using dependency injection in spring. I know i can do this using #Service annotation but i don';t know the syntax. can someone help me to solve this problem.

put a plain #Service annotation over your AppConfigureServiceImpl (you don't have to specify the "appConfigureServiceImpl" like you did).
Then have the service instance injected automatically in your controller by adding the following inside ConfigureApplicationController class:
#Autowired
AppConfigureService appConfigureService;
Now you can just call it like this: appConfigureService.getListOfAllAppConfigure();
Note that for the injection to happen, you need to make sure that you have set componentScan property in your configuration file to scan the packages that contain the classes to be injected. In your case, the package that contains AppConfigureServiceImpl.
<context:component-scan base-package="com.my.servicepackage" />
Note also that you should do the same with your dao instead of creating a new application context and getting it from the there. I.e. add a
#Autowired
AppConfigureDAO appConfigureDAO;
property inside your AppConfigureServiceImpl and use that.

Related

How to use #Autowired annotation two or more different Component class for same service?

For example, have a class like as follows.
First XService service in class A is not null but second XService service in AmountValidator is null.I get NullPointerException I try to create bean new it works and then I get same exception when call AmountValidateService outsideRestService in XService.
How can I use XService everywhere that I use #Autowired annotation.
My main class:
#Service
class A extends AbstractA implements IA {
#Autowired
XService service; //first autowired definition. code go to check() method. service not null now.
public doSometing(){
validator.check();
service.methodA();
super.AbstractMethod();
}
}
Validator class used in class A :
class Validator<T> implements IValidator<T> {
public void check(){
rule.check(); // rule have a implements IValidator eg: amountValidator, dateValidator class
}
}
AmountValidator added to rule in class Validator.
#Component
class AmountValidator implements IValidator<T>{
#Autowired
XService service; // code comes here service is null. same service class mentioned above class A.
#Override
public void check(){
service.validateAmount(); // nullPointerException.
}
}
My main Service
#Component
class XService {
#Autowired
AmountValidateService outsideRestService;
public validateAmount(){
outsideRestService.validate(); // nullPointer when create XService with the `New` keyword
}
}
You have an error cause you are trying to create components/beans/services yourself. As i mentioned in comment when you create components yourself it - #Autowired doesn't work - thats you've got NPE
All classes annotated with #Component, #Service are considered special classes which are instantiated by Spring automatically via DI, instantiating them with new defeats the purpose of DI.
These special classes are named Spring Beans.
Every time the application starts, the framework instances all Spring Beans, and all #Autowired fields are injected by Spring automatically. But the Spring Beans must be defined somewhere in the class path. Else you will receive a NoSuchBeanDefinitionException
As an attempt to answer the question, since I don't have a stack trace nor all the Spring Bean definitions:
When you instantiate XService using new XService() your new instance will not actually initialize the field AmountValidateService outsideRestService, effectively leaving it as null.
You may set the field yourself but as I mentioned earlier, it defeats the purpose of DI
Your question is not complex, it is incomplete.

#Service/#Controller annotations creates a new bean without using #Bean annotation

I have a class which I have annotated with #Service #Scope
#Slf4j
#Service
#Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ProductDataModel {
#Value("${message}")
private String message;
The above code seems to be creating a bean for ProductDataModel, without using the #Bean annotation.
I am using #Autowired ProductDataModel productDataModel in my code, and the dependency productDataModel is not null, when used with above piece of Code.
How come the above code is creating bean ??
Ideally, I would have expected bean to created only when I use the below code
//I am not using this piece of code in my program., for reference only
#Configuration
public class OSCConfig {
#Bean
#Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
ProductDataModel productDataModel(){
return new ProductDataModel();
}
Can someone explain the difference between 2 pieces of code and when to use which one.
As #M. Deinum pointed out that we don't need to specify #Bean for each class when we declare #Service or #Controller annotation they are picked up by Spring Container if component-scanning is enabled for that package.
So good use case for using #Bean could be that
If the Class is in third party jar and you can not add #Service/#Controller annotations
If you want to add some custom logic inside the #Bean annotate methods
The #Service annotation is picked up by Spring when scanning for objects to create (as part of a package scan). It is an specialisation of the spring #Component annotation, but doesn't really add much other than providing an indication to users about its intended purpose. The #Controlller annotation is similar, but the bean created has specific characteristics.
The #Bean annotation as you have used it is also used when creating objects, and in this context it is on a method in a Configuration class, therefore the bean created is of the type returned by the method.

Whats bean in spring and what is not

lets say I have code like this:
#Repository
public class Foo{
}
#Service
public class Boo{
#Autowired
private Foo foo;
}
so now what here are we calling bean? Bean is the object of Foo type of refrence "foo" BUT are Boo class annotated as Service and Foo as Repository ALSO beans? Ihve been using spring for a while now but this basic question makes me feel bad for not knowing...
In the context of Spring, A bean is a spring managed object. Here spring managed means an object created, initialised, managed, destroyed by Spring IoC container.
Whenever we mark a class with #Component, Spring IOC container will create object for your class and manage it, Whenever we can simply get it from ApplicationContext, or access it using #Autowired/#Resource/#Inject annotations
We can also use #Controller, #Repository, #Service, #ControllerAdvice, #Configuration,#Aspect in place of #Component to tell more specifically that our class is a service or a repository or an aspect etc.
We can also use #Bean annotation to create a bean from method return value
#Configuration
public class SolrConfig {
#Value("${spring.data.solr.host}") String solrUrl;
#Bean
public SolrServer solrServer() {
return new HttpSolrServer(solrUrl);
}
#Bean(name = "solrTemplate")
public SolrTemplate solrTemplate() {
return new SolrTemplate(new HttpSolrServer(solrUrl), RULE_ENGINE_CORE);
}
}
All of your application components (#Component, #Service, #Repository, #Controller etc.) will be automatically registered as Spring Beans
http://docs.spring.io/autorepo/docs/spring-boot/current/reference/html/using-boot-spring-beans-and-dependency-injection.html
Defining Beans can be thought of as replacing the keyword new.
Further information can be found here which might be helpful for understanding Beans in Spring.

Injection of HttpServletRequest in GWTP ActionHandler using Spring

I have implemented my GWT application using Spring + GWTP.
I want to access HttpServletRequest object into my ActionHandler class.
The ServerModule is Spring Configuration class (using #Configuration Annotation).
Now problem is how can I inject the current HttpServletRequest, ServletContext, ServletConfig in my ActionHandler using Spring.
Following is the definition of ServerModule:
#Configuration
#Import(DefaultModule.class)
public class ServerModule extends HandlerModule
{
#Bean
public UserVerficationActionHandler getUserVerificationActionActionHandler()
{
return new UserVerficationActionHandler();
}
}
In above Example I just want to inject the HttpServletRequest using Spring.
Any guidance on this highly appreciated.
Thanks.
The RequestProvider is your solution. It's a class in gwt-dispatch-server jar.
DefaultModule provides the RequestProvider bean so that you can just inject it into places you need it.
Take a look at the sourcec code for com.gwtplatform.dispatch.server.spring.configuration.DefaultModule which creates the RequestProvider as a DefaultRequestProvider which then defers to RequestContextHolder to do the work.
See the link for what you need to add to your web.xml to get this to work.

How to overwrite Spring service beans by name, using annotations only

Given I have a Spring bean configured as
#Service("myService")
public class DefaultService extends MyService {
}
and a class using this bean
public class Consumer {
#Autowired
#Qualifier("myService")
private MyService service;
...
}
I now want my project, that includes the preceding classes, to have Consumer another implementation of MyService being injected. Therefore I would like to overwrite the bean myService
#Service("myService")
public class SpecializedService implements MyService {
}
resulting in Consumer carrying now an instance of SpecializedService instead of DefaultService. By definition I cannot have two beans with the same name in the Spring container. How can I tell spring, that the definition of the new service shall overwrite the older one? I don't want to modify the Consumer class.
Either define the service bean explicitly
<bean id="myService" class="x.y.z.SpecializedService" />
or component-scan it.
In either event, in your application context, avoid explicitly defining DefaultService and avoid component-scanning it.
Exclude it from component-scan by using a filter
<component-scan base-package="your-package">
<exclude-filter type="regex" expression="DefaultService" />
</component-scan>
Not sure if there is a way to do it with only annotations (other than removing the #Service annotation from DefaultService).
Annotation based wiring happens before the XML based configuration, that means beans defined in XML will
overwrite those wiring done by Annotations.
So defining it explicitely in XML, like Willie has said will do the work
<bean id="myService" class="x.y.z.SpecializedService" />
Spring recommends using XML for service and repository beans and annotation for MVC beans. It also recommends #Autowired without component scanning. But Annotation are in general encouraged, although it merges code and configuration together (against seperation of concerns).
Second thing is to use #Qualifiers("id of declared bean") where it is being passed.
I know , its late . Still posting it.
You should have different names for different implementations of MyService.
For instance
#Service("mySpecializedService")
public class SpecializedService implements MyService {
}
#Service("myService")
public class DefaultService extends MyService {
}
While autowiring them ( say in Controller) , you may use #Qualifier to inject desired implementation as mentioned below.
To get default implementation
#Autowired
#Qualifier("myService")
MyService myService;
To get specialized implementation
#Autowired
#Qualifier("mySpecializedService")
MyService myService;

Resources