Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | 51CTO学院 | CSDN程序员研修院 | OSChina 博客 | 腾讯云社区 | 阿里云栖社区 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏多维度架构

5.3. SpringApplication

		

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@ComponentScan({"cn.netkiller.controller"})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}
		
	

5.3.1. 运行 Spring boot 项目

5.3.1.1. Linux systemd

/etc/systemd/system/spring.service

			
####################################################
# Homepage: http://netkiller.github.io
# Author: netkiller<netkiller@msn.com>
# Script: https://github.com/oscm/shell
# Date: 2015-11-03
####################################################
[Unit]
Description=Spring Boot Application
After=network.target

[Service]
User=www
Group=www
Type=oneshot
WorkingDirectory=/www/netkiller.cn/api.netkiller.cn
ExecStart=/usr/bin/java -jar your_jar_file.jar --spring.config.location=appliction-production.properties --spring.profiles.active=profile
#ExecStop=pkill -9 -f  
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
			
			

5.3.1.2. 传统 init.d 脚本

			
#!/bin/bash
##############################################
# Author: netkiller<netkiller@msn.com>
# Homepage: http://www.netkiller.cn
# Date: 2017-02-08
# $Author$
# $Id$
##############################################
# chkconfig: 345 100 02
# description: Spring boot application
# processname: springbootd
# File : springbootd
##############################################
BASEDIR="/www/netkiller.cn/api.netkiller.cn"
JAVA_HOME=/srv/java
JAVA_OPTS="-server -Xms2048m -Xmx8192m -Djava.security.egd=file:/dev/./urandom"
PACKAGE="api.netkiller.cn-0.0.2-release.jar"
CONFIG="--spring.config.location=$BASEDIR/application.properties"
USER=www
##############################################
NAME=springbootd
PROG="$JAVA_HOME/bin/java $JAVA_OPTS -jar $BASEDIR/$PACKAGE $CONFIG"
LOGFILE=/var/tmp/$NAME.log
PIDFILE=/var/tmp/$NAME.pid
ACCESS_LOG=/var/tmp/$NAME.access.log
##############################################

function log(){
	echo "$(date -d "today" +"%Y-%m-%d %H:%M:%S") $1	$2" >> $LOGFILE
}

function start(){
	if [ -f "$PIDFILE" ]; then
		echo $PIDFILE
		exit 2
	fi

	su - $USER -c "$PROG & echo \$! > $PIDFILE"
	log info start
}
function stop(){
	[ -f $PIDFILE ] && kill `cat $PIDFILE` && rm -rf $PIDFILE
	log info stop
}
function status(){
	ps aux | grep $PACKAGE | grep -v grep | grep -v status
	log info status
}
function reset(){
	pkill -f $PACKAGE
  	[ -f $PIDFILE ] && rm -rf $PIDFILE
	log info reset
}

case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
	status)
		status
		;;
	restart)
		stop
		start
		;;
	log)
		tail -f $LOGFILE
		;;
	reset)
		reset
		;;
	*)
		echo $"Usage: $0 {start|stop|status|restart|log|reset}"
esac
exit $?

			
			

5.3.1.3. 编译用于Tomcat的 War

			
package demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application extends SpringBootServletInitializer {

    private static Class<Application> applicationClass = Application.class;
    
    public static void main(String[] args) {
        SpringApplication.run(applicationClass, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(applicationClass);
    }
}		
			
			

5.3.2. @SpringBootApplication

@SpringBootApplication 是 @Configuration, @EnableAutoConfiguration 跟 @ComponentScan 的集合。

			
@SpringBootApplication
			
		

5.3.2.1. 排除 @EnableAutoConfiguration 加载项

				
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)				
				
			

5.3.3. 获取 Resources 目录中的静态文件

			
	package cn.netkiller;
	
	import java.io.File;
	import java.io.IOException;
	import java.net.URL;
	
	import org.springframework.core.io.ClassPathResource;
	import org.springframework.web.bind.annotation.GetMapping;
	import org.springframework.web.bind.annotation.RestController;
	
	@RestController
	public class TestController {
	
		public TestController() {
			// TODO Auto-generated constructor stub
		}
	
		@GetMapping("/test")
		public String test() {
			ClassPathResource resource = new ClassPathResource("test.ttf");
			File file = null;
			try {
				file = resource.getFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
			// InputStream inStream = new FileInputStream(file.getPath());
			// BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream()));
			return file.getPath();
		}
		@GetMapping("/test1")
		public String test1() {
			URL url = Thread.currentThread().getContextClassLoader().getResource("test.ttf");
			return url.getPath();
		}
		
	}		
			
		

5.3.4. @EnableAutoConfiguration

exclude 排除配置,下面例子是排除 DataSource配置

			
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
			
		

5.3.5. @ComponentScan

@ComponentScan 注入会扫描 @Controller 与 @RestController

			
@ComponentScan
@ComponentScan({"cn.netkiller.controller"})
@ComponentScan({"cn.netkiller.controller", "cn.netkiller.rest"})
			
		

5.3.6. @EntityScan 实体扫描

			
@EntityScan("common.domain")
			
		

5.3.7. @EnableJpaRepositories

扫描 Jpa 仓库

			
@EnableJpaRepositories("common.domain")			
			
		

5.3.8. CharacterEncodingFilter

			
	public @Bean Filter characterEncodingFilter() {
		CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
		characterEncodingFilter.setEncoding("UTF-8");
		characterEncodingFilter.setForceEncoding(true);
		return characterEncodingFilter;
	}			
			
		

5.3.9. 隐藏 Banner

隐藏 Spring Boot Banner

			
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.1.RELEASE)
			
		
			
public static void main(String[] args) {
    SpringApplication app = new SpringApplication(Application.class);
    app.setShowBanner(false);
    app.run(args);
}
			
		

5.3.10. 实体与仓库扫描

			
@EntityScan(basePackages = { "cn.netkiller.model" }) 
@EnableJpaRepositories(basePackages = { "cn.netkiller.repository" })			
			
		

5.3.11. 列出 Beans

			
package cn.netkiller;

import java.util.Arrays;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan
@EnableMongoRepositories
@EnableJpaRepositories
@EnableScheduling
public class Application {

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

		ApplicationContext ctx = SpringApplication.run(Application.class, args);

		System.out.println("Let's inspect the beans provided by Spring Boot:");

		String[] beanNames = ctx.getBeanDefinitionNames();
		Arrays.sort(beanNames);
		for (String beanName : beanNames) {
			System.out.println(beanName);
		}

	}
}
			
		

5.3.12. Tomcat 端口

		
@Configuration
public class TomcatConfiguration implements EmbeddedServletContainerCustomizer {

	int ports[] = { 8080, 8081, 8082 };

	@Override
	public void customize(ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) {

		if (ports != null) {
			// 判断如果是Tomcat才进行如下配置
			if (configurableEmbeddedServletContainer instanceof TomcatEmbeddedServletContainerFactory) {

				TomcatEmbeddedServletContainerFactory tomcat = (TomcatEmbeddedServletContainerFactory) configurableEmbeddedServletContainer;

				for (int port : ports) {
					// 一个Connecter监听一个端口,指定协议为HTTP/1.1
					Connector httpConnector = new Connector("HTTP/1.1");
					httpConnector.setPort(port);
					tomcat.addAdditionalTomcatConnectors(httpConnector);
				}

			}
		}
	}
}
		
		

5.3.13. 配置项设定

			
public static void main(String[] args) {
    SpringApplication.run(Backend.class,
        "--spring.application.name=backend",
        "--server.port=9000"
    );
  }			
			
		

5.3.14. spring.profiles.active

			
在 Java 代码中激活 profile

直接指定环境变量来激活 profile:

System.setProperty("spring.profiles.active", "test");

在 Spring 容器中激活 profile:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("development");
ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class);
ctx.refresh();			
			

		

5.3.15. @Profile("dev") / @ActiveProfiles("dev")

不同环境运行不同的逻辑

		
@Configuration
public class DataSourceConfig {

    @Bean
    @Profile("dev")
    public DataSource devDataSource() {
        System.out.println(" dev DataSource !!");
        BasicDataSource basicDataSource = new BasicDataSource();
        basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        basicDataSource.setUrl("jdbc:mysql://localhost:3308/neo");
        basicDataSource.setUsername("root");
        basicDataSource.setPassword("123456");
        return basicDataSource;
    }

    @Bean
    @Profile("prod")
    public DataSource prodDataSource() {
        System.out.println(" prod DataSource !!");
        BasicDataSource basicDataSource = new BasicDataSource();
        basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        basicDataSource.setUrl("jdbc:mysql://localhost:3306/neo");
        basicDataSource.setUsername("root");
        basicDataSource.setPassword("123456");
        return basicDataSource;
    }
}
		
		

匹配多个环境

		
@Profile({"dev", "test", "grey", "prod"})		
		
		

5.3.16. 设置默认时区

     
package cn.netkiller;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.annotation.PostConstruct;
import java.util.TimeZone;

@SpringBootApplication
@EnableDiscoveryClient
@EnableTransactionManagement
@EnableFeignClients(basePackages = {"cn.netkiller.feign.*","cn.netkiller.openfeign.*"})
@MapperScan("cn.netkiller.dao")
public class Application {
    @PostConstruct
    void setDefaultTimezone() {
        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
    }

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