In my project created by SpringBoot,
I have added 2 main classes with @SpringBootApplication.
Because if I use STS I can choose one main application when start to debug.
But I found that while SpringDemoApplication is up ,RabbitMQApplication is also running.
Is this specification ? working appropriately?
Here this is sample to reproduce https://github.com/MariMurotani/SpringDemo/tree/6_rabbitMQ
SpringDemoApplication
package demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
public class SpringDemoApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(SpringDemoApplication.class);
ApplicationContext context = application.run(args);
}
}
RabbitMQApplication
package demo;
import java.util.Date;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import demo.configs.Const;
import demo.dto.Mail;
@SpringBootApplication
public class RabbitMQApplication implements CommandLineRunner {
@Autowired
ApplicationContext context;
@Autowired
RabbitTemplate rabbitTemplate;
@Bean
Queue queue() {
return new Queue(Const.RabbitMQMessageQue, false);
}
@Bean
TopicExchange exchange() {
return new TopicExchange("spring-boot-exchange");
}
@Bean
Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(Const.RabbitMQMessageQue);
}
@Bean
SimpleMessageListenerContainer container(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(Const.RabbitMQMessageQue);
//container.setMessageListener(listenerAdapter);
return container;
}
/*
For asyncronized receiving
@Bean
Receiver receiver() {
return new Receiver();
}
@Bean
MessageListenerAdapter listenerAdapter(Receiver receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}*/
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(RabbitMQApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println("Waiting five seconds...");
while(0 < 1){
for(int i = 0 ; i < 5 ; i++){
String object = (String)rabbitTemplate.receiveAndConvert(Const.RabbitMQMessageQue);
if(object != null){
try{
System.out.println(new Date().toGMTString() + ": " + object);
ObjectMapper mapper = new ObjectMapper();
Mail mail = mapper.readValue(object, Mail.class);
System.out.println(mail.getToAddress() + " , " + mail.getStrContent());
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
Thread.sleep(10000);
}
}
}
The @SpringBootApplication
annotation is a shortcut annotation for @Configuration
, @EnableAutoConfiguration
, and @ComponentScan
.
http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-using-springbootapplication-annotation.html
The default behavior of @ComponentScan
is to look for @Configuration
and @Component
classes within the same package and all sub-packages of the annotated class. Since all your classes are in the same package, when you start any one of them Spring will find the others and treat them like @Configuration
classes, and register their beans, etc.
So yes, this is expected behavior given your project setup. Put each @SpringBootApplication
class in a separate subpackage if you don't want this to happen for local testing. If this moves beyond a demo at some point you'll probably want to come up with a better setup (subprojects for each @SpringBootApplication
perhaps).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With