jeudi 29 janvier 2015

Is it possible to use a @Profile("test") configuration to override the default?

We have a spring project which defined some classes without @Profile, like:



interface MyService {
String changeName(String name);
}

@Service
class MyService1 implements MyService {
public String changeName(String name) {
return name.toUpperCase();
}
}

@Controller
class SampleController {

@Autowired
private MyService myService;

@ResponseBody
@RequestMapping(value = "/hello/{name}", produces = "application/json")
String home(@PathVariable String name) {
return "Hello " + myService.changeName(name) + "!";
}

}


I can start a server to run it:



@EnableAutoConfiguration
@ComponentScan
@Configuration
public class Main {
public static void main(String[] args) throws Exception {
new SpringApplicationBuilder(Main.class)
.run(args);
}
}


Then I can visit the url http://localhost:8080/hello/freewind and got the text Hello FREEWIND!.


I want to start a testing server, so I want to find a way to replace the existing MyService1 with a mock class. And I found there is a @Profile seems promissing:



@Profile("test")
@Configuration
class TestConfig {

@Bean
public MyService myService() {
return new MyService() {
public String changeName(String name) {
return "###" + name + "###";
}
};
}

}


And change Main to active profile test:



new SpringApplicationBuilder(Main.class)
.profiles("test")
.run(args);


But when I start it, it reports error:



Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [web.MyService] is defined:
expected single matching bean but found 2: myService1,myService


If I want it work, I HAVE to change the existing code to give the MyService1 a different profile, like:



@Profile("dev")
@Configuration
class DevConfig {

@Bean
public MyService myService() {
return new MyService1();
}

class MyService1 implements MyService {
public String changeName(String name) {
return name.toUpperCase();
}
}

}


Now it will work well, but I don't want to modify the existing code.


Is there any way to use @Profile without modifying the existing code, or is there any other way to replace an existing bean with a custom bean?


Aucun commentaire:

Enregistrer un commentaire