浅谈:Spring Boot原理分析(更多细节解释在代码注释中)

通过@EnableAutoConfiguration注解加载Springboot内置的自动初始化类(加载什么类是配置在spring.factories),这这些类中在基于spring4.0提供的Condition接口进行Bean的初始化。

Condition

⚫ 自定义条件:
① 定义条件类:自定义类实现Condition接口,重写 matches 方法,在 matches 方法中进行逻辑判断,返回
boolean值 。 matches 方法两个参数:
• context:上下文对象,可以获取属性值,获取类加载器,获取BeanFactory等。
• metadata:元数据对象,用于获取注解属性。
② 判断条件: 在初始化Bean时,使用 @Conditional(条件类.class)注解
⚫ SpringBoot 提供的常用条件注解:
• ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean
• ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean
• ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean

案列说明Condition

首先搭建springboot的项目

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><!--    导入springboot父工程spring-boot-starter-parent,我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.fs</groupId><artifactId>springboot-condition</artifactId><version>1.0-SNAPSHOT</version><dependencies><!--        引入starter--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!--        引入redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency></dependencies></project>

自定义注解

MyCondition

package com.fs.condition;import org.springframework.context.annotation.Conditional;import java.lang.annotation.*;/*
自定义注解*///元注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented//判断条件: 在初始化Bean时,使用 @Conditional(条件类.class)注解
@Conditional(ClassCondition.class)
public @interface MyCondition {String[] value();
}

自定义定义条件类:自定义类实现Condition接口,重写 matches 方法,在 matches 方法中进行逻辑判断,返回boolean值 。 matches 方法两个参数:
• context:上下文对象,可以获取属性值,获取类加载器,获取BeanFactory等。
• metadata:元数据对象,用于获取注解属性。
判断条件: 在初始化Bean时,使用 @Conditional(条件类.class)注解

package com.fs.condition;import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;import java.util.Map;
/*
springboot的底层实现原理是什么?基于spring4.0提供的Condition接口进行实现*///创建一个自定义类来实现org.springframework.context.annotation.Condition;接口
public class ClassCondition implements Condition {/*** @param conditionContext conditionContext上下文,共享数据的,用于获取环境,IOC容器,ClassLoader对象* @param annotatedTypeMetadata 注解元数据,拿到Conditional注解的元数据,可以用于获取注解定义的属性值* @return 返回布尔,确定加上@Conditional(ClassCondition.class)后这个bean是否创建*/@Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {//返回的布尔就表示spring是否创建对应的bean//可以根据条件判断是否创建bean//return false;//可以按照Class.forName(类全路径包名)来判断是否导入这个类的依耐是否导入,导入就创建//获取我们注解属性值Map<String, Object> map = annotatedTypeMetadata.getAnnotationAttributes(MyCondition.class.getName());String[] values = (String[])map.get("value");boolean flag = true;try {for (String className : values) {Class<?> cls = Class.forName(className);}} catch (ClassNotFoundException e) {flag = false;}return flag;}
}

在配置类中使用

package com.fs.config;import com.fs.condition.ClassCondition;
import com.fs.condition.MyCondition;
import com.fs.pojo.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;@Configuration
public class UserConfig {//    @Bean
//    //指定一个自定义类实现Condition接口是否spring创建这bean
//    @Conditional(ClassCondition.class)
//    public User user(){//        return new User();
//    }//使用自定义的Condition注解@Bean//使用自定义的注解@MyCondition("com.fs.pojo.User")public User user2(){return new User();}//指定application配置文件有这个属性就加载bean@Bean@ConditionalOnProperty(name = "xiaofu",havingValue = "haha")public User user3(){return new User();}
}

application.yml

由于我们配置类中使用了@ConditionalOnProperty(name = “xiaofu”,havingValue = “haha”)
所以需要在application配置文件中编写配置,才会让配置类中的bean初始化

# 设置属性,让user3初始化
xiaofu: haha

主启动测试

package com.fs;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;/*** @ComponentScan() 扫描引导类所在包及其子包*/
@SpringBootApplication
public class SpringBootCondition {public static void main(String[] args) {//启动springboot的应用,返回spring的IOC容器ConfigurableApplicationContext context = SpringApplication.run(SpringBootCondition.class, args);/*SpringBoot是如何知道要创建哪个Bean的?比如SpringBoot是如何知道要创建RedisTemplate的?因为我们在maven引入了spring-boot-starter-data-redis这个依耐,就会根据@Conditional注解去判断是否初始化这个bean*///获取bean,获取redisTemplateObject redisTemplate = context.getBean("redisTemplate");System.out.println(redisTemplate);//我们自定义了配置类,UserConfig 类中的方法也加上了@Condition注解来判断是否注入这个Object user2 = context.getBean("user2");System.out.println(user2);//使用springboot提供的注解来判断是否初始化beanObject user3 = context.getBean("user3");System.out.println(user3);}
}

说明我们自定义的Condition 条件判断没有问题

切换内置web服务器

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!--排除tomcat依赖--><exclusions><exclusion><artifactId>spring-boot-starter-tomcat</artifactId><groupId>org.springframework.boot</groupId></exclusion></exclusions></dependency><!--引入jetty的依赖--><dependency><artifactId>spring-boot-starter-jetty</artifactId><groupId>org.springframework.boot</groupId></dependency>

如何自定义Stater?(@Import 自定义Enable注解 spring.factories 等)

@Enable*注解
SpringBoot中提供了很多Enable开头的注解,这些注解都是用于动态启用某些功能的。而其底层原理是使用@Import注解导入一些配置类,实现Bean的动态加载。

@Import注解
@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中。而@Import提供4中用法:
① 导入Bean
② 导入配置类 @Import(spring配置类.class)
③ 导入 ImportSelector 实现类。一般用于加载配置文件中的类
④ 导入 ImportBeanDefinitionRegistrar 实现类。

@EnableAutoConfiguration 注解
⚫ @EnableAutoConfiguration 注解内部使用 @Import(AutoConfigurationImportSelector.class)来加载配置类。
⚫ 配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当 SpringBoot 应用启动时,会自动加载这些配置类,初始化Bean
⚫ 并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的Bean

实现步骤
① 创建 redis-spring-boot-autoconfigure 模块
② 创建 redis-spring-boot-starter 模块,依赖 redis-springboot-autoconfigure的模块
③ 在 redis-spring-boot-autoconfigure 模块中初始化 Jedis 的
Bean。并定义META-INF/spring.factories 文件
④ 在测试模块中引入自定义的 redis-starter 依赖,测试获取
Jedis 的Bean,操作 redis。

① 创建 redis-spring-boot-autoconfigure 模块

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><!--    导入springboot父工程spring-boot-starter-parent,我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.fs</groupId><artifactId>redis-spring-boot-autoconfigure</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!--引入jedis依赖--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency></dependencies></project>

RedisAutoConfiguration 自定义的AutoConfiguration类

package com.fs.config;import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;/*
自定义的AutoConfiguration类*/
@Configuration
//这个注解会去找我们给的的Class.class,并且这个类要被@ConfigurationProperties注解标记
//说白了 @EnableConfigurationProperties 相当于把使用 @ConfigurationProperties 的类进行了一次注入。
@EnableConfigurationProperties(RedisProperties.class)
//这个注解表示判断环境中是否有对应字节码文件才初始化Bean,判断是否导入了Jedis的包,当前项目环境中有没有Jedis这个类
//有才会去初始化我们当前类下方法的bean
@ConditionalOnClass(Jedis.class)
public class RedisAutoConfiguration {@Bean//这个Condition注解的意思就是判断环境中没有对应Bean才初始化Bean,//IOC容器中有么有名为jedis的bean,有就不初始化我们这个bean@ConditionalOnMissingBean(name="jedis")public Jedis jedis(RedisProperties redisProperties){//初始化bean,并将我们的属性类中的值给这个beanreturn new Jedis(redisProperties.getHost(),redisProperties.getPort());}
}

RedisProperties 自定义的简陋的redis连接属性类

package com.fs.config;
/*
自定义的简陋的redis连接属性类*/import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
//docker start -i 容器名称
@Component
//ConfigurationProperties这个注解就会去application.yml中去找对应的一组属性值,并赋值给我们自定义的属性类的成员变量
@ConfigurationProperties(prefix = "xiaofu.redis")
public class RedisProperties {//提供2个属性,从application配置文件中去读取.指定默认指,用户不在application中配置,就使用默认的private String host = "localhost";private Integer port = 6379;public String getHost() {return host;}public void setHost(String host) {this.host = host;}public Integer getPort() {return port;}public void setPort(Integer port) {this.port = port;}
}

User 实体类,用于测试自定义@Enable注解使用

package com.fs.pojo;public class User {}

UserConfig User配置类,注入User Bean

package com.fs.config;import com.fs.pojo.User;
import org.springframework.context.annotation.Bean;public class UserConfig {@Beanpublic User user(){return new User();}
}

EnableAutoUser 自定义Enable注解

package com.fs.enable;import com.fs.config.UserConfig;
import org.springframework.context.annotation.Import;import java.lang.annotation.*;
//元注解信息
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
//自定义注解,当加上这个注解,就会自动将配置类中的bean注入到IOC容器中
@Import(UserConfig.class)
public @interface EnableAutoUser {}

spring.factories 自定义starter核心的配置文件

# 这个配置文件一定要在resources/META-INF/spring.factories下
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.fs.config.RedisAutoConfiguration

② 创建 redis-spring-boot-starter 模块,依赖 redis-springboot-autoconfigure的模块

创建starter工程(遵循Spring starter命名规范)

pom.xml 主要引入我们自定义的 redis-springboot-autoconfigure

<?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><!--    导入springboot父工程spring-boot-starter-parent,我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.fs</groupId><artifactId>redis-spring-boot-starter</artifactId><version>1.0-SNAPSHOT</version><dependencies><!--引入自定义的redis-configure--><dependency><groupId>com.fs</groupId><artifactId>redis-spring-boot-autoconfigure</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>
</project>

创建springboot工程测试我们自定义的starter 模块

pom.xml 引入我们自定义的 redis-spring-boot-starter 模块

<?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><!--    导入springboot父工程spring-boot-starter-parent,我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.fs</groupId><artifactId>test-Redis-restart</artifactId><version>1.0-SNAPSHOT</version><dependencies>
<!--        引入自定义的restart--><dependency><groupId>com.fs</groupId><artifactId>redis-spring-boot-starter</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>
</project>

application.yml

# 使用我们自定义的autoconfigure 的RedisProperties 属性类@ConfigurationProperties(prefix = "xiaofu.redis")
xiaofu:redis:host: 47.112.174.148port: 6379

主启动 MyStarterApp

package com.fs;import com.fs.enable.EnableAutoUser;
import com.fs.pojo.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import redis.clients.jedis.Jedis;@SpringBootApplication
//使用自定义的注解,就会自动加载自定义注解上@Import(UserConfig.class)的配置类,注入bean
@EnableAutoUser
public class MyStarterApp {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(MyStarterApp.class, args);//从容器中获取我们自定义的Jedis,//由于@SpringBootApplication注解中的@EnableAutoConfiguration//会自动去加载META-INF/spring.factories,该配置文件中定义了大量的配置类//我们自定义的redis-spring-boot-autoconfigure项目也写了一个spring.factories,所以就会把我们自定义的RedisAutoConfiguration配置类加载初始化beanJedis bean = context.getBean(Jedis.class);System.out.println(bean);//由于我们配置文件中指定了host地址,测试一下bean.set("haha","xixi");String haha = bean.get("haha");System.out.println(haha);//获取userUser user = context.getBean(User.class);System.out.println(user);}
}

测试结果

SpringBoot 监控概述

SpringBoot自带监控功能Actuator,可以帮助实现对程序内部运行情况监控,比如监控状况、Bean加载情况、配置属性、日志信息等。

SpringBoot 监控使用
① 导入依赖坐标

org.springframework.boot
spring-boot-starter-actuator

② 访问http://localhost:8080/acruator

SpringBoot 监控 - Spring Boot Admin

SpringBoot 监控 - Spring Boot Admin
⚫ Spring Boot Admin是一个开源社区项目,用于管理和监控SpringBoot应用程序。
⚫ Spring Boot Admin 有两个角色,客户端(Client)和服务端(Server)。
⚫ 应用程序作为Spring Boot Admin Client向为Spring Boot Admin Server注册
⚫ Spring Boot Admin Server 的UI界面将Spring Boot Admin Client的Actuator Endpoint上的一些监控信息。

使用步骤

admin-server:
① 创建 admin-server 模块
② 导入依赖坐标 admin-starter-server
③ 在引导类上启用监控功能@EnableAdminServer
admin-client:
① 创建 admin-client 模块
② 导入依赖坐标 admin-starter-client
③ 配置相关信息:server地址等
④ 启动server和client服务,访问server

Spring Boot Admin 项目搭建

springboot-admin-service

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><!--    导入springboot父工程spring-boot-starter-parent,我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.fs</groupId><artifactId>springboot-admin-service</artifactId><version>1.0-SNAPSHOT</version><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-server</artifactId><version>2.3.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
application.yml
server:port: 9000
主启动 SpringbootAdminService
package com.fs;import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;//开启adminserver
@EnableAdminServer
@SpringBootApplication
public class SpringbootAdminService {public static void main(String[] args) {SpringApplication.run(SpringbootAdminService.class,args);}
}

springboot-admin-client

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><!--    导入springboot父工程spring-boot-starter-parent,我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.fs</groupId><artifactId>springboot-admin-client</artifactId><version>1.0-SNAPSHOT</version><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-starter-client --><dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-client</artifactId><version>2.3.0</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
application.yml
spring:boot:admin:client:url: http://127.0.0.1:9000 # 注意这里必须写ip 指定adminserver的地址application:name: xiaofu-springboot
management:endpoint:health:show-details: alwaysendpoints:web:exposure:include: "*" # 将所有的监控endpoint暴露出来
主启动 SpringbootAdminClient
package com.fs;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringbootAdminClient {public static void main(String[] args) {SpringApplication.run(SpringbootAdminClient.class,args);}
}

controller

package com.fs.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/hello")
public class TestController {@RequestMapping("/world")public String add(){return "HelloWorld";}
}
启动两个项目,打开浏览器测试

就可以一目了然啦

springboot的项目打成war包

==1 改造启动类 ==

package com.fs;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;/*
将springboot的项目打成war包1.先在pom文件中设置war2.将主启动类extends SpringBootServletInitializer3.重写SpringApplicationBuilder configure(SpringApplicationBuilder builder){}方法4.在configure方法中返回builder.sources(主启动.class);*/
@SpringBootApplication
public class HelloWorld extends SpringBootServletInitializer {public static void main(String[] args) {SpringApplication.run(HelloWorld.class,args);}@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {return builder.sources(HelloWorld.class);}
}

2 改造POM.xml
<packaging>war</packaging>

<?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><!--    导入springboot父工程spring-boot-starter-parent,我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.1.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.fs</groupId><artifactId>springboot-HelloWorld</artifactId><version>1.0-SNAPSHOT</version>
<!--    将springboot项目打成war包--><packaging>war</packaging><properties><java.version>1.8</java.version></properties><dependencies><!--        引入web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build>
<!--        给war包起个名字--><finalName>HelloWorld</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

点名maven的package就能得到war包的springboot项目啦

浅谈:Spring Boot原理分析,切换内置web服务器,SpringBoot监听项目(使用springboot-admin),将springboot的项目打成war包相关推荐

  1. java+caching+system_浅谈Spring boot cache使用和原理

    缓存要解决的问题:一个程序的瓶颈在于数据库,我们也知道内存的速度是大大快于硬盘的速度的.当我们需要重复地获取相同的数据的时候,我们一次又一次的请求数据库或者远程服务,导致大量的时间耗费在数据库查询或者 ...

  2. 终端命令运行php文件路径,PHP -S命令 PHP内置web服务器

    摘要:PHP 5.4.0起, CLI SAPI 提供了一个内置的Web服务器.这个内置的Web服务器主要用于本地开发使用,不可用于线上产品环境.URI请求会被发... PHP 5.4.0起, CLI ...

  3. php如何启动内置web服务器

    前言: PHP从5.4开始,就提供了一个内置的web服务器. 当然这个主要是用来做本地的开发用的. 不能用于线上环境. 现在我就介绍一下这个工具如何使用. 前提: php已经加入到本地电脑的环境变量中 ...

  4. java 内置web服务器_Webstorm 2016内置web服务器配置

    Javascript之匿名函数 分析: 1.所谓匿名函数,从字面意思理解,就是没有名字的函数,js 用()来代替(注意,是英文状态下的括号) 2.定义形式: function (){ //to add ...

  5. php 使用内置web服务器

    执行 : php -S localhost:8234 -t ./ -t 后面指定目录, 不加-t 参数则为当前目录, 访问时优先打开 index.php index.html 参考 http://ph ...

  6. php web server setup,PHP本地开发利器:内置Web Server

    PHP 5.4.0起, CLI SAPI 提供了一个内置的Web服务器. 命令:php -S 这个内置的Web服务器主要用于本地开发使用,不可用于线上产品环境. URI请求会被发送到PHP所在的的工作 ...

  7. 浅谈 Spring IOC和AOP

    浅谈 Spring IOC和AOP IOC 控制反转 以前创建对象的主动权和时机是由于自己把握的,现在将这种权利转移到Spring容器中,并且根据配置文件去创建对象管理对象 ioc的注入方式有三种:构 ...

  8. 浅谈实时数据库系统原理及其应用

    浅谈实时数据库系统原理及其应用 孙俊彦   苏州大学计算机科学与技术学院 摘要: 现代的工程和时间关键型应用对数据库的实时性和对数据直接分析和处理的能力要求特别高,单纯的传统关系数据库已经不能满足需要 ...

  9. 浅谈“三层结构”原理与用意(转帖)

    浅谈"三层结构"原理与用意 序 在刚刚步入"多层结构"Web应用程序开发的时候,我阅读过几篇关于"asp.net三层结构开发"的文章.但其多 ...

最新文章

  1. 201521123111《Java程序设计》第2周学习总结
  2. 树莓派400键盘计算机发布!全新的电路板布局,更快,更酷!
  3. c++:MFC中sqlite3的使用(附实际案例)
  4. Python常用的模块的使用技巧
  5. 单点登录的原理与CAS技术的研究
  6. 1109: 数根(函数专题)
  7. 做网管这么久了,每个月只是拿1000元的工资
  8. Java基础-序列化和反序列化
  9. 汇编指令:push、pop
  10. Eclipse中Tab的配置(设置为按一下Tab键,效果是按4次空格,而不是4个空格的缩进)
  11. 2018中国大学生程序设计竞赛-网络选拔赛题解
  12. java 子类调用父类内部类_java 如何在子类方法中实例化父类的内部类?
  13. 181026英语每日一句
  14. zabbix3.0.4导入中文模板后乱码问题处理
  15. 推荐几个偷网站的小工具
  16. 三星 smarttv android,三星SmartView
  17. 服务器lnixs系统,Navicat for MySQL v12.1.19 强大的数据库管理和开发工具 _ 黑苹果乐园...
  18. java毕业设计——基于java+mysql+socket的即时通讯软件设计与实现(毕业论文+程序源码)——即时通讯软件
  19. 基于PHP+MySQL大连真爱果汁厂管理系统的设计与实现
  20. CUPS之gutenprint生成ppd文件

热门文章

  1. book: Effective Java
  2. Emit学习-进阶篇-定义事件
  3. java 关键字volatile的作用
  4. Java 理论与实践: 线程池与工作队列
  5. 第二次Soring冲刺计划第二天(个人)
  6. jQuery_事件学习
  7. Nginx基础知识之————日志管理
  8. 【转】各种媒体数据以 base64 编码方式直接嵌入网页中的写法
  9. Windows_API_函数 参考大全
  10. 实现日志管理的两种方式:aop、拦截器