I have a scenario wherein my ServiceImpl and Business Class implements the same interface. But im unable to autowire both of them.
#RestController
#RequestMapping("/myservice")
public interface myInterface{
#RequestMapping(value="/getSomething/{input}", method=RequestMethod.GET)
doSomething(String input);
}
Now i have two classes which implements same interface
#Component
#Qualifier("doSomethingImpl")
public class DoSomethingImpl implements myInterface{
#Autowired
#Qualifier("businessLayer")
myInterface businessLayer;
doSomething(#PathVariable String input){
//my logic here
}
}
#Component
#Qualifier("businessLayer")
public class BusinessLayer implements myInterface{
doSomething(#PathVariable String input){
//my logic here
}
}
Now when i run it on server i'm getting following error
Cannot map handler 'DoSomethingImpl' to URL path
[/myservice/getSomething/{input}]: There is already handler of type
[class com.mypackage.business.BusinessLayer] mapped.
Could someone please help me to resolve this error
The problem is that both controllers are being mapped to the same path. I suggest you change your code to something like:
public interface myInterface{
#RequestMapping(value="/getSomething/{input}", method=RequestMethod.GET)
public Whatever doSomething(String input) {
//whatever
}
}
#RequestMapping("something")
#RestController
public class DoSomethingImpl implements myInterface{
}
#RequestMapping("somethingElse")
#RestController
public class BusinessLayer implements myInterface{
}
Related
I have a Service class that has a generic type and a setController method that is based on the same generic type. the generic type of the servic object is only known at the time of declaration.
The problem is now when i define a ControllerImpl where the generic type is defined the #Autowired method of setController does not use that component.
Has somebody an idea how to fix it and keep the ServiceImpl generic. (it would work when i define the typ in ServiceImpl as well).
The following example show the problem i'm facing with:
#SpringBootTest
#ActiveProfiles("local")
public class AccessTest {
#Autowired
private ServiceA<BeanA> service;
#Test
void test(){
Assertions.assertNotNull(service.controller);
}
interface ValueGetter{
}
static class BeanA implements ValueGetter{
}
static class AbstractService<B extends ValueGetter>{
Controller<B> controller;
#Autowired
void setController(#Nullable Controller<B> controller){
this.controller = controller;
}
}
interface Controller<B extends ValueGetter>{
void doSomething(B value);
}
//not inner class
#Service
public class ServiceA<B extends AccessTest.ValueGetter> extends AccessTest.AbstractService<B> {
}
//not inner class
#Component
public class ControllerImpl implements AccessTest.Controller<AccessTest.BeanA> {
#Override
public void doSomething(final AccessTest.BeanA value) {
}
}
}
I have a controller class which further calls service class method. An AOP #Before aspect is applied on the service class method.
package com.example;
#RestController
public class BookController {
#Autowired
BookService bookService;
#RequestMapping(value = "/getBookDetails", method = RequestMethod.GET,
#RequestBody BookRequest bookRequest))
public String processBookDetails() {
System.out.println("Inside controller class");
String details = bookService.getBookDetailsInfo(bookRequest,bookName);
}
}
Service class
package com.example;
#Service
public class BookServiceImpl implements BookService {
#Override
public String getBookDetailsInfo(BookRequest bookRequest,String bookName) {
//some code
// call getBookDEtails
getBookDetails(bookInfoObj)
returns "Book details";
}
#CallBookInfo-- custom annotation for aspect which needs to be executed before getBookDetails is called
getBookDetails(BookInfoObj obj){
}
An aspect is written to be executed #Before the method getBookDetails() of BookServiceImpl
//Custom annotation
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface CallBookInfo{}
//Aspect
#Aspect
#Configuration
public class BookAspect {
#Before("#annotation(com.example.CallBookInfo)")
public Object beforeBookAdvice(JoinPoint joinpoint) {
System.out.println("Start aspect");
Object result= null;
try {
BookRequest obj= joinpoint.getArgs();
System.out.println("End aspect");
}
catch(Exception e) {}
return result;
}
}
Execution goes as below,
Controller calls BookServiceImpl.getDetailsInfo() method.
getBookDetails() is called inside this method after some conditions
#Before Aspect is called before the getBookDetails() due to the custom
annotation #CallBookInfo
How to get the BookRequest object which was passed from the Controller class to the service class and after some processing return it back to the service class from the aspect
Thank you in advance !!
I want to use aspect method depending on specific annotation. In my scenario when I mark up my business class with #Service annotation it is not working, but when I change it to component it starts to work.
Here is sample:
My Aspect class...
#Aspect
#Component
public class MyAspect
{
....
#Around(value="#annotation(com.myannoation.annotation.MyAnnotate)")
public Object MyMethod(ProceedingJoinPoint proceedingJoinPoint) throws Exception {
return ......
}
.......
#Component-->it is work
#Service -->it is not working
#Path("api/myapisample")
public class myapicontroller {
#POST
#Produces(MediaType.APPLICATION_JSON)
public Response confirm(MyRequest request)
{
.....
I am autowiring a property(its a component) in an abstract class, This is not working , always coming a null; The same property has been autowired in other abstract class which is working absolutely fine. can some one please tell me , what would be the problem?
public abstract class BaseRegistry {
#Autowired
PropertyConfig propertyConfig;
}
#Repository
public class OptionsRegistry extends BaseRegistry{
}
#Component
public class PropertyConfig {
}
I'm having a Spring boot application in which based on a variable, I need to call corresponding implementation classes of an interface. This is what I have right now:
public interface Parent{
public void call();
}
public class ABC implements Parent{
public void call(){
System.out.println("Called ABC");
}
}
public class XYZ implements Parent{
public void call(){
System.out.println("Called XYZ");
}
}
#Service("caller")
public class Caller{
#Autowired
protected OrderInfoRepository orderInfoRepository;
AnnotationConfigApplicationContext context;
public Caller(){
context = new AnnotationConfigApplicationContext(Config.class);
}
public void callMethod(String param){
Parent p = (Parent) context.getBean(param+"_Caller");
p.call();
}
}
#Configuration
public class Config{
#Bean(name="ABC_Caller")
public Parent getABC(){
return new ABC();
}
#Bean(name="XYZ_Caller")
public Parent getXYZ(){
return new XYZ();
}
}
#Repository
public interface MyRepo extends Repository<MyDAO, Long> {
// ....
}
Basically what I want to do is, based on the param passed to Caller.callMethod(), I want to add "_Caller" to the param, and call the corresponding implementation class. So, I'm defining a #Configuration class, where I define which implementation class to return. And then using the AnnotationConfigApplicationContext, I get the corresponding bean. This works fine.
The problem I'm having is, when I try to Autowire anything in the implementation classes, I get a NoSuchBeanDefinitionException. For instance, when I autowire in the implementation class ABC
public class ABC implements Parent{
#Autowired
MyRepo myRepo;
public void call(){
System.out.println("Called ABC");
}
}
I get Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.persistence.repositories.MyRepo] when I try to start the application. However, when I do the Autowiring in the Caller class instead, it works fine. I had asked a similar question a while back, but was not able to resolve it. Any ideas?