zl程序教程

您现在的位置是:首页 >  后端

当前栏目

SpringBoot 标签之启动

SpringBoot 启动 标签
2023-09-14 09:02:31 时间

在SpringBoot中入口我们使用:

package com.sankuai.qcs.regulation.traffic;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.reactive.config.EnableWebFlux;

@SpringBootApplication
@EnableWebFlux
@EnableScheduling
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

因为是SpringBoot启动,是全注解启动形式,里面的任何注解和XML在启动的时候都可以加载到内存中,XML 和注解可以混合使用,

因为SpringBoot本来就是为了减少XML文件的,所以尽量使用注解

比如:

成都项目:

package com.sankuai.qcs.regulation.traffic.common.config;
import com.dianping.squirrel.client.impl.redis.router.RouterType;
import com.dianping.squirrel.client.impl.redis.spring.RedisClientBeanFactory;
import com.google.common.base.Objects;
import com.meituan.mafka.client.consumer.IMessageListener;
import com.sankuai.qcs.regulation.traffic.common.constant.CommonConstants;
import com.sankuai.qcs.regulation.traffic.common.consumer.MessageConsumer;
import com.sankuai.qcs.regulation.traffic.common.util.HttpUtil;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.context.annotation.*;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.web.reactive.config.EnableWebFlux;

/**
 * Created by ramon on 2017/11/9.
 */
@Configuration
@ImportResource(locations = {"classpath:rhinoConfig.xml"})
public class SpringBeanConfig {

    /**
     * 动态配置
     * @return
     */
    @Bean("mccConfig")
    public PropertySourcesPlaceholderConfigurer mccConfig() {
        MccPropertyPlaceholderConfigurer mccPropertyPlaceholderConfigurer = new MccPropertyPlaceholderConfigurer();
        mccPropertyPlaceholderConfigurer.setAppKey(CommonConstants.APP_NAME);
        mccPropertyPlaceholderConfigurer.setScanBasePackage("com.sankuai.qcs.regulation");
        return mccPropertyPlaceholderConfigurer;
    }

    /**
     * 提供netty http server的配置
     * @return
     */
    @Bean
    public NettyReactiveWebServerFactory httpServer() {
        NettyReactiveWebServerFactory nettyReactiveWebServerFactory = new NettyReactiveWebServerFactory();
        int httpPort = HttpUtil.getHttpPort();
        nettyReactiveWebServerFactory.setPort(httpPort);
        return nettyReactiveWebServerFactory;
    }

    /**
     * 消息监听
     * @return
     */
    @Bean("messageConsumer")
    public MessageConsumer messageConsumer(@Value("${app.name}")String appName, @Value("${topic.name}")String topic, @Value("${group.name}")String groupName, IMessageListener regulationMessageListener) {
        MessageConsumer messageConsumer = new MessageConsumer();
        messageConsumer.setAppKey(appName);
        messageConsumer.setBg("waimai");
        messageConsumer.setTopic(topic);
        messageConsumer.setConsumerGroup(groupName);
        messageConsumer.setConsumerListener(regulationMessageListener);
        messageConsumer.start();
        return messageConsumer;
    } 

}

在messageConsumer方法中:参数有个:

@Value("${app.name}")String appName

他的意思是:参数appName有个默认值:就是@Value("${app.name}");而 ${app.name}指的是,系统会在项目中遍历所有的properties文件,并找到app.name加载到指定的值;

后面的参数是:

 IMessageListener regulationMessageListener

springboot会根据 IMessageListener 的实现类,自动的注册到项目中,因为

IMessageListener 有两个实现类:
package com.meituan.mafka.client.consumer;

public abstract class IDeadLetterListener implements IMessageListener {
    private DeadLetterConsumer consumer;

    public IDeadLetterListener() {
    }

    public boolean retry(Object msg, long delayTime) throws Exception {
        return this.consumer.retry(msg, delayTime);
    }

    public void setConsumer(DeadLetterConsumer consumer) {
        this.consumer = consumer;
    }
}

还有个:

package com.sankuai.qcs.regulation.traffic.mq;

import com.dianping.cat.Cat;
import com.meituan.mafka.client.consumer.ConsumeStatus;
import com.meituan.mafka.client.consumer.IMessageListener;
import com.meituan.mafka.client.message.MafkaMessage;
import com.meituan.mafka.client.message.MessagetContext;
import com.sankuai.qcs.regulation.traffic.common.util.JsonUtil;
import com.sankuai.qcs.regulation.traffic.service.MessageManageService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;

/**
 * 数据监听
 * Created by panyuanyuan02 on 2018/1/30.
 */
@Service
public class RegulationMessageListener implements IMessageListener {
    @Resource
    private MessageManageService messageManageService;
    private Logger logger = LoggerFactory.getLogger(RegulationMessageListener.class);
    @Override
    public ConsumeStatus recvMessage(MafkaMessage message, MessagetContext context) {
        try {
            String body = (String) message.getBody();
            logger.info("Recv message:{}", body);
            MafkaMessageObject mafkaMessageObject = JsonUtil.fromStr(body, MafkaMessageObject.class);
            messageManageService.saveMessage(mafkaMessageObject.getMsgType(), mafkaMessageObject.getData());
        } catch (Exception e) {
            logger.error("process message exception", e);
            Cat.logMetricForCount("process_message_exception");
        }
        return ConsumeStatus.CONSUME_SUCCESS;
    }

}

请注意第二个实现类上面的@Service注解, springboot 能找到第二个,因为有注解标签@Service,但是找不到第一个,以为第一个就是一个普通的类,并没有注解标签;

里面有标签:@Configuration;

也有引入的配置文件:

@ImportResource(locations = {"classpath:rhinoConfig.xml"})

但是如果是Spring项目的话,

@Configuration有可能不加载;

Spring 启动有两种启动方式,一种是

 ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:application.xml");
}
这种方法不能加载@Configuration,但是可以加载@Service等;
比如:
package com.sankuai.qcs.regulation.shanghai;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.Log4jConfigurer;

import java.io.FileNotFoundException;

/**
 * @author ssc Feb 1, 2018
 */
public class App {

    private static Logger LOGGER = LoggerFactory.getLogger(App.class);

    static {
        try {
            Log4jConfigurer.initLogging("classpath:log4j2.xml", 5000);
        } catch (FileNotFoundException e) {
            LOGGER.error("App#static initializer init log config error", e);
        }
    }

    public static void main(String[] args) throws Throwable {



        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:application.xml");
}
}

这种方式的话,@Configuraton是不会加载的;

需要使用另一种加载方式:

        ApplicationContext ac1 = new AnnotationConfigApplicationContext("com.sankuai.qcs.regulation.shanghai");

参数是基础的包名称,这样 @Configuration就可以加载上了;