由于前些日子比较忙着一些工作事情,导致没有更新连续性的教程文章,现在往后一段时间我打算写当下比较流行的Spring Boot框架教程,从入门到进阶的使用方式,希望该系列文章对大家有一些开发上的帮助,本系列教程需要有一定的开发经验基础,如有不正确的地方望指出;前言到此,我们开启教程之旅.
步骤1.
准备我们的POM.xml文件,我使用的是Spring Boot 2.0.0版本,JDK建议1.8+(关键),其中我们可以看到配置移除了内嵌Tomcat插件,因为我们真实应用项目中需要比较多自定义的容器,所以我不建议使用内嵌的Tomcat作为开发使用
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.soho</groupId>
<artifactId>soho</artifactId>
<version>3.0.6</version>
<packaging>pom</packaging>
<properties>
<maven.local.server>https://localhost</maven.local.server>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mybatis.boot.version>1.3.1</mybatis.boot.version>
<mysql.version>5.1.18</mysql.version>
<fastjson.version>1.2.46</fastjson.version>
<druid.version>1.1.0</druid.version>
<log4j.version>1.2.17</log4j.version>
<shiro.spring.version>1.4.0</shiro.spring.version>
<servlet.version>3.1.0</servlet.version>
<commons.io.version>2.4</commons.io.version>
</properties>
<!-- maven install不过滤指定资源 -->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
<!-- Spring Boot 启动父依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<!-- Spring Boot Web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 移除嵌入式tomcat插件 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring Boot Aop 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- Spring Boot Freemarker 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- Spring Boot Ehcache需要的依赖-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<!-- Spring Boot Logback需要的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!-- Spring Boot Mybatis 依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.boot.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
</dependencies>
</project>
步骤2.
编写我们的启动类,其中我们应该设计有两种启动实现类,一种是读取本地application.properties方式,一种是读取zookeeper配置数据方式,所以我们需要设计一个合理的启动类,方便我们切换启动方式
以下类是Spring读取配置数据,我们可在该扩展类操作我们的一些配置数据加密解密,比如数据库的账号和密码等等,其中AESUtils可自行编写一个AES加密工具类即可,decodeKeys是我们需要解密的配置数据集合
/**
* Spring加载配置文件
*
* @author shadow
*/
public abstract class AbstractPropertyConfigurer extends PropertyPlaceholderConfigurer {
private String[] decodeKeys;
public AbstractPropertyConfigurer(String filePath, String[] decodeKeys) {
this.decodeKeys = decodeKeys;
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource resource = resolver.getResource(filePath);
setLocation(resource);
}
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties properties) {
properties = appendProperties(properties);
properties = decodeProperties(properties);
super.processProperties(beanFactoryToProcess, properties);
}
public Properties decodeProperties(Properties properties) {
String encrypt_key = properties.getProperty("default.projectKey");
encrypt_key = StringUtils.isEmpty(encrypt_key) ? "" : AESUtils.decrypt(encrypt_key);
if (!StringUtils.isEmpty(decodeKeys) && decodeKeys.length > 0) {
for (String decodeKey : decodeKeys) {
String data = properties.getProperty(decodeKey);
if (!StringUtils.isEmpty(data)) {
properties.put(decodeKey, AESUtils.decrypt(data, encrypt_key));
}
}
}
return properties;
}
public abstract Properties appendProperties(Properties properties);
}
默认配置类读取实现
/**
* Spring加载配置文件
*
* @author shadow
*/
public class DefaultPropertyConfigurer extends AbstractPropertyConfigurer {
public DefaultPropertyConfigurer(String filePath, String[] decodeKeys) {
super(filePath, decodeKeys);
}
@Override
public Properties appendProperties(Properties properties) {
return properties;
}
}
默认SpringBoot启动类实现
/**
* Spring Boot启动类实现
*
* @author shadow
*/
public class DefaultServletInitializer extends SpringBootServletInitializer {
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(getClass());
}
public PropertyPlaceholderConfigurer initPropertyPlaceholderConfigurer(String filePath, String[] decodeKeys) {
if (StringUtils.isEmpty(filePath)) {
filePath = "classpath:application.properties";
}
if (decodeKeys == null || decodeKeys.length == 0) {
decodeKeys = new String[]{"spring.datasource.username", "spring.datasource.password"};
}
return new DefaultPropertyConfigurer(filePath, decodeKeys);
}
}
步骤3.
Application.java 非内嵌Tomcat启动需要从该类初始化
/**
* @author shadow
*/
@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan(basePackages = {"com.soho"})
public class Application extends DefaultServletInitializer {
@Bean
public PropertyPlaceholderConfigurer initPropertyPlaceholderConfigurer() {
return super.initPropertyPlaceholderConfigurer(null, null); // 本地启动方式
}
}
application.properties配置参数文件
########################################################
### log
########################################################
logging.config=classpath:logback.xml
########################################################
### database
########################################################
spring.datasource.database=MySQL
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test_db
spring.datasource.username=55867b5f32a962b4d5e9e4247b21f7a5
spring.datasource.password=c1ab036d736cc8f87465b7d2d4162642
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.filters=stat,wall,log4j
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
spring.datasource.logSlowSql=true
spring.datasource.mgbXmlLocation=classpath*:/com/soho/demo/**/mapper/*.xml
########################################################
### spring aop
########################################################
spring.aop.auto=true
spring.aop.proxy-target-class=true
########################################################
### freemarker
########################################################
spring.freemarker.allow-request-override=false
spring.freemarker.cache=true
spring.freemarker.check-template-location=true
spring.freemarker.charset=UTF-8
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=false
spring.freemarker.expose-session-attributes=false
spring.freemarker.expose-spring-macro-helpers=false
spring.freemarker.suffix=.ftl
spring.freemarker.template-loader-path=/WEB-INF/ftl/
########################################################
### mybatis
########################################################
mybatis.config-locations=classpath:mybatis/mybatis-config.xml
########################################################
### default
########################################################
default.domain=http://localhost:8011
default.projectCode=000001
default.projectKey=9a41fba77913364c4be505fcd8dab18495685ab0846fe6e88b3006dbed0daf84
步骤4.
把项目部署到Tomcat上,然后启动Tomcat容器即可,附上启动信息
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.0.RELEASE)
2018-06-19 10:53:02 INFO com.soho.demo.Application >>> No active profile set, falling back to default profiles: default
2018-06-19 10:53:02 INFO o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext >>> Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@11a08579: startup date [Tue Jun 19 10:53:02 CST 2018]; parent: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@7099c281
2018-06-19 10:53:03 INFO o.s.b.f.s.DefaultListableBeanFactory >>> Overriding bean definition for bean 'filterRegistrationBean' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=druidConfiguration; factoryMethodName=filterRegistrationBean; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/soho/spring/configuration/DruidConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=com.alibaba.druid.spring.boot.autoconfigure.DruidWebStatFilterConfiguration; factoryMethodName=filterRegistrationBean; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/alibaba/druid/spring/boot/autoconfigure/DruidWebStatFilterConfiguration.class]]
2018-06-19 10:53:03 WARN o.m.s.mapper.ClassPathMapperScanner >>> No MyBatis mapper was found in '[com.soho.demo]' package. Please check your configuration.
2018-06-19 10:53:03 WARN o.s.c.a.ConfigurationClassEnhancer >>> @Bean method Application.initPropertyPlaceholderConfigurer is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.
2018-06-19 10:53:04 DEBUG c.s.s.e.DefaultPropertyConfigurer >>> Loading properties file from class path resource [application.properties]
19-Jun-2018 10:53:08.089 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [E:\apache-tomcat-8.5.30\webapps\manager]
19-Jun-2018 10:53:08.252 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [E:\apache-tomcat-8.5.30\webapps\manager] has finished in [161] ms
2018-06-19 10:53:09 INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker >>> Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$c9eb5301] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-19 10:53:09 INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker >>> Bean 'initCacheManager' of type [com.soho.spring.cache.imp.SimpleCacheManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-19 10:53:09 INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker >>> Bean 'shiroDataCache' of type [com.soho.spring.shiro.cache.ShiroDataCache] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-19 10:53:09 INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker >>> Bean 'simpleShiroCacheManager' of type [com.soho.spring.shiro.cache.SimpleShiroCacheManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-19 10:53:09 INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker >>> Bean 'shiroInitializeServiceImp' of type [com.soho.shiro.ShiroInitializeServiceImp] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-19 10:53:09 INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker >>> Bean 'deftConfig' of type [com.soho.spring.model.DeftConfig] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-19 10:53:09 INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker >>> Bean 'shiroConfiguration' of type [com.soho.spring.configuration.ShiroConfiguration$$EnhancerBySpringCGLIB$$32876d86] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-19 10:53:10 INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker >>> Bean 'initSecurityManager' of type [org.apache.shiro.web.mgt.DefaultWebSecurityManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-19 10:53:10 INFO o.s.web.context.ContextLoader >>> Root WebApplicationContext: initialization completed in 7424 ms
本章教程主要让大家明白如何通过外部Tomcat启动我们的Spring Boot应用,以及多方式启动(zookeeper方式启动后续讲解)并扩展配置数据的加密解密操作,如果有同学喜欢本来原本的内嵌Tomcat启动方式可查看官方示例,由于比较简单我就不多说了
如果喜欢我的教程文章,请点下赞或收藏,如有疑惑可随时私信或评论区@我,感激不尽