springboot已经深入人心,免去繁琐的xml配置,用着得心应手,但是你知道它是怎么运行起来的呢?如何嵌入Embedded Tomcat的呢?本文单一的main方法,教你实现自己的springboot
maven项目
//pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.ddddd</groupId>
<artifactId>springboottest3</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.16</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>tttt.Test</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
//Test.java
package tttt;
import org.apache.catalina.*;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import java.io.File;
/**
* @author zhanghui
* @date 2019/6/26
*/
public class Test {
public static void main(String[] args) {
System.out.println("current working dir:"+System.getProperty("user.dir")+File.separator);
Tomcat tomcat = new Tomcat();
// tomcat config
//CATALINA_BASE home dir
String baseDir = "./tomcat_tmp/";
tomcat.setBaseDir(baseDir);
tomcat.setPort(8080);
tomcat.setHostname("127.0.0.1"); //default localhost
// tomcat component config, server->service->connector->engine->host->context
Server server = tomcat.getServer(); //one server for one tomcat
Service service = tomcat.getService();
Connector connector = tomcat.getConnector(); // default HTTP/1.1 connector
Engine engine = tomcat.getEngine();
Host host = tomcat.getHost();
Context context = tomcat.addContext(host,"","../"); // dir is "", means create webapps dir under baseDir
// servlet config
AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
appContext.scan("myapp");
String servletName = "myspringmvc";
Tomcat.addServlet(context,servletName,new DispatcherServlet(appContext));
context.addServletMappingDecoded("/*",servletName);
try {
tomcat.start();
} catch (LifecycleException e) {
e.printStackTrace();
}
tomcat.getServer().await();
}
}
//TestController.java
package myapp.controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/**
* @author zhanghui
* @date 2019/7/3
*/
@RestController
public class TestController {
@GetMapping({"","/"})
public String hi(){
return "hi";
}
// default not mapping url
@GetMapping("/**")
public String defaultPage(HttpServletRequest request){
StringBuilder stringBuilder = new StringBuilder(request.getRequestURL().toString());
if(!StringUtils.isEmpty(request.getQueryString()))
stringBuilder.append("?" + request.getQueryString());
return "defaultPage:"+ stringBuilder.toString();
}
}
manven打包package后,springboottest3-1.0-jar-with-dependencies.jar
java -jar D:\proj\springboottest3\target\springboottest3-1.0-jar-with-dependencies.jar
牛逼不?点赞,评论,关注,是对我最大的肯定,谢谢
后记:加入jdbc查询
//pom.xml
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jdbc</artifactId>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
//DbConfig.java
package myapp.controller;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
/**
* @author zhanghui
* @date 2019/6/20
*/
@Configuration
public class DbConfig {
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://192.168.1.196:3306?useSSL=false");
dataSource.setUsername("");
dataSource.setPassword("");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
return dataSource;
}
@Bean
public JdbcTemplate jdbc(){
return new JdbcTemplate(dataSource());
}
}
//TestController.java
@Autowired
private JdbcTemplate jdbcTemplate;
@GetMapping("/jdbc")
public String jdbc(){
jdbcTemplate.execute("use voice_robot");
List<Map<String, Object>> ress = jdbcTemplate.queryForList("show tables");
System.out.println(ress.size());
return "jdbc";
}
后记2:log4j2日志,很像springboot日志
//pom.xml
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.12</version>
</dependency>
//Test.java 有main方法的类内,静态块,初始化日志配置
static {
ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
AppenderComponentBuilder console = builder.newAppender("stdout", "Console");
LayoutComponentBuilder standard = builder.newLayout("PatternLayout");
standard.addAttribute("disableAnsi",false);
// %c{2.} short class name, %c{36} whole class name
standard.addAttribute("pattern", "%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} %highlight{${LOG_LEVEL_PATTERN:-%5p}}{FATAL=red blink, ERROR=red, WARN=yellow bold, INFO=green, DEBUG=green bold, TRACE=blue} %style{%pid}{magenta} [%15.15t] %style{%-40.40C{1.}}{cyan} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%rEx}");
console.add(standard);
builder.add(console);
RootLoggerComponentBuilder rootLogger = builder.newRootLogger(Level.ALL);
rootLogger.add(builder.newAppenderRef("stdout"));
builder.add(rootLogger);
LoggerComponentBuilder logger = builder.newLogger("com", Level.DEBUG);
logger.add(builder.newAppenderRef("stdout"));
logger.addAttribute("additivity", false);
builder.add(logger);
Configurator.initialize(builder.build());
}
//TestController.java
@Slf4j
@RestController
public class TestController {
//看看日志效果
log.error("jdbc...........................");
后记3:加入spring session
【spring session的实现方式】
tomcat加入一个DelegatingFilterProxy的filter,这个只是一个filter的代理,由他接管,当tomcat调用filter时,就会调用这个代理,然后这个代理会在spring中找以他的FilterName定义的bean,这个bean就是真正的filter (SessionRepositoryFilter),这个filter会替换掉原来的HTTPSession为HttpSessionWrapper,HttpSessionWrapper实现将session写入redis
//pom.xml
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
//RedisConfig.java
package myapp.controller;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
import org.springframework.session.web.http.SessionRepositoryFilter;
import javax.servlet.Filter;
/**
* @author zhanghui
* @date 2019/7/3
*/
@Configuration
public class RedisConfig {
@Bean
public RedisConnectionFactory redisConnectionFactory(){
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName("192.168.1.196");
factory.setPort(6379);
return factory;
}
@Bean
public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory connectionFactory){
RedisTemplate<Object,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
return redisTemplate;
}
@Bean("springSessionRepositoryFilter")
public Filter delegatingFilterProxy(RedisTemplate<Object,Object> redisTemplate){
return new SessionRepositoryFilter(new RedisOperationsSessionRepository(redisTemplate));
}
}
//Test.java 配置tomcat加入filter
import org.springframework.web.filter.DelegatingFilterProxy;
import org.apache.tomcat.util.descriptor.web.FilterDef;
import org.apache.tomcat.util.descriptor.web.FilterMap;
FilterDef filter1definition = new FilterDef();
filter1definition.setFilterName("springSessionRepositoryFilter");
filter1definition.setFilterClass(DelegatingFilterProxy.class.getName());
context.addFilterDef(filter1definition);
FilterMap filter1mapping = new FilterMap();
filter1mapping.setFilterName("springSessionRepositoryFilter");
filter1mapping.addURLPattern("/*");
context.addFilterMap(filter1mapping);