RabbitAdmin
在上篇中遗留AmqpAdmin没有讲解,现在来看下该部分代码public AmqpAdmin amqpAdmin(CachingConnectionFactory connectionFactory) {
return new RabbitAdmin(connectionFactory);
}
public RabbitAdmin(ConnectionFactory connectionFactory) {
this.connectionFactory = connectionFactory;
Assert.notNull(connectionFactory, "ConnectionFactory must not be null");
this.rabbitTemplate = new RabbitTemplate(connectionFactory);
}
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("127.0.0.1:5672");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
connectionFactory.setPublisherConfirms(true); //必须要设置
return connectionFactory;
}
private volatile CacheMode cacheMode = CacheMode.CHANNEL;
public class RabbitAdmin implements AmqpAdmin, ApplicationContextAware, InitializingBean {
...
}
public void afterPropertiesSet() {
synchronized (this.lifecycleMonitor) {
if (this.running || !this.autoStartup) {
return;
}
if (this.connectionFactory instanceof CachingConnectionFactory &&
((CachingConnectionFactory) this.connectionFactory).getCacheMode() == CacheMode.CONNECTION) {
logger.warn("RabbitAdmin auto declaration is not supported with CacheMode.CONNECTION");
return;
}
this.connectionFactory.addConnectionListener(new ConnectionListener() {
// Prevent stack overflow...
private final AtomicBoolean initializing = new AtomicBoolean(false);
@Override
public void onCreate(Connection connection) {
if (!initializing.compareAndSet(false, true)) {
// If we are already initializing, we don't need to do it again...
return;
}
try {
initialize();
}
finally {
initializing.compareAndSet(true, false);
}
}
@Override
public void onClose(Connection connection) {
}
});
this.running = true;
}
}
public void addConnectionListener(ConnectionListener listener) {
super.addConnectionListener(listener);
// If the connection is already alive we assume that the new listener wants to be notified
if (this.connection != null) {
listener.onCreate(this.connection);
}
}
private List delegates = new CopyOnWriteArrayList();
Exchange
@Bean
public DirectExchange defaultExchange() {
return new DirectExchange(EXCHANGE);
}
以上代码创建一个交换机,交换机类型为direct
public Queue queue() {
return new Queue("spring-boot-queue", true); //队列持久
}
@Bean
public Binding binding() {
return BindingBuilder.bind(queue()).to(defaultExchange()).with(AmqpConfig.ROUTINGKEY);
}
public static DestinationConfigurer bind(Queue queue) {
return new DestinationConfigurer(queue.getName(), DestinationType.QUEUE);
}
public class Binding extends AbstractDeclarable {
public static enum DestinationType {
QUEUE, EXCHANGE;
}
private final String destination;
private final String exchange;
private final String routingKey;
private final Map arguments;
private final DestinationType destinationType;
...
}
@Bean
public SimpleMessageListenerContainer messageContainer() {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
container.setQueues(queue());
container.setExposeListenerChannel(true);
container.setMaxConcurrentConsumers(1);
container.setConcurrentConsumers(1);
container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认
container.setMessageListener(new ChannelAwareMessageListener() {
@Override
public void onMessage(Message message, Channel channel) throws Exception {
byte[] body = message.getBody();
System.out.println("receive msg : " + new String(body));
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费
}
});
return container;
}
private volatile List queueNames = new CopyOnWriteArrayList();
添加队列信息
container.setMaxConcurrentConsumers(1);
container.setConcurrentConsumers(1);
设置并发消费者数量,默认情况为1
container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认
设置消费者成功消费消息后确认模式,分为两种
public interface SmartLifecycle extends Lifecycle, Phased {
boolean isAutoStartup();
void stop(Runnable callback);
}
其中的isAutoStartup设置为true时,会自动调用Lifecycle接口中的start方法,既然我们为源码分析,也简单看下这个聪明的声明周期接口是如何实现它的聪明方法的
protected void finishRefresh() {
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isDebugEnabled()) {
logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate LifecycleProcessor with name '" +
LIFECYCLE_PROCESSOR_BEAN_NAME +
"': using default [" + this.lifecycleProcessor + "]");
}
}
}
getLifecycleProcessor().onRefresh()调用DefaultLifecycleProcessor中方法onRefresh,调用startBeans(true)
private void startBeans(boolean autoStartupOnly) {
Map lifecycleBeans = getLifecycleBeans();
Map phases = new HashMap();
for (Map.Entry entry : lifecycleBeans.entrySet()) {
Lifecycle bean = entry.getValue();
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
int phase = getPhase(bean);
LifecycleGroup group = phases.get(phase);
if (group == null) {
group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
phases.put(phase, group);
}
group.add(entry.getKey(), bean);
}
}
if (phases.size() > 0) {
List keys = new ArrayList(phases.keySet());
Collections.sort(keys);
for (Integer key : keys) {
phases.get(key).start();
}
}
}
Map lifecycleBeans = getLifecycleBeans();
获取所有实现Lifecycle接口bean,执行bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup()判断,如果bean同时也为Phased实例,则加入到LifecycleGroup中,随后phases.get(key).start()调用start方法
接下来要做的事情就很明显:要了解消费者具体如何实现,查看SimpleMessageListenerContainer中的start是如何实现的。
至此~~整合RabbitMQ源码分析准备工作完成,下一篇中正式解读消费者的实现。
转载请注明