springBoot
一 springBoot的特性
创建独立的Spring应用程序
直接嵌入Tomcat,Jetty或Undertow(无需部署WAR文件)
提供“初始”的POM文件内容,以简化Maven配置
尽可能自动配置Spring
提供生产就绪的功能,如指标,健康检查和外部化配置
绝对无代码生成,也不需要XML配置
二:通过Web界面构建
1. 访问:http://start.spring.io/
2. 选择构建工具Maven Project、Spring Boot版本2.3.2以及一些工程基本信息
3. 点击Generate Project下载项目压缩包
4. 导入到你的工程,如果是IDEA,则需要:
a.菜单中选择File–>New–>Project from Existing Sources...
b.选择解压后的项目文件夹,点击OK
c.点击Import project from external model并选择Maven,点击Next到底为止。
d.若你的环境有多个版本的JDK,注意到选择Java SDK的时候请选择Java 8以上的版本
三、Spring IOC
ioc(inversion of control,控制反转)
1.依赖注入DI(dependency injection)
容器通过调用set方法或者构造器来建立对象之间的 依赖关系。 IOC是目标,DI是手段。
在Spring的工作方式中,所有的类都会在spring容器中登记,告诉spring这是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。 所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是 spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫 控制反转。
四、AOP
1、面向切面编程,非侵入时编程,如打印日志信息。
spring aop使用了动态代理技术在运行期织入增强的代码,使用了两种代理机制,一种是基于jdk的动态代理,另一种是基于CGLib的动态代理。
Jdk是基于反射。Cjlib 基于字节码。Jdk的动态代理是基于接口的。如果是类就用cjlib。
五、注解
1. @RequestMapping: 是一个用来处理请求地址映射的注解,它提供路由信息,可用于类或方 法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。它告诉Spring任何 来自"/"路径的HTTP请求都应该被映射到index方。@RestController注解告诉Spring以字符串的形式渲染结果,并直接返回给调用者。
2. @Profiles: Spring Profiles提供了一种隔离应用程序配置的方式,并让这些配置只能在特定环境下生效。任何@Component或@Configuration都能被@Prefiles标记,从而限制加载它时机。
3. @ResponseBody: 表示该方法的返回结果直接写入 HTTP response body中,一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上 @Responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@Responsebody后,会直接返回json数据。
4. @Component:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。一般公 共的方法我会用上这个注解。
5. @Autowired: byType方式,把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成 员变量、方法及构造函数进行标注,完成自动装配的工作。当加上(required=false)时,就算找不到bean也不会报错。
6. @RequestParam:用在方法的参数前面。 @RequestParam String a
=request.getParameter("a");
7. @PathVariable:路径变量。 RequestMapping("user/get/mac/{macAddress}") public String getByMacAddress(@PathVariable String macAddress){ //do something; }
8. 全局处理异常的: @ControllerAdvice: 包含@Component。可以被扫描到, 统一处理异常。 @ExceptionHandler(Exception.class): 用在方法上面表示遇到这个异常就执行以下方法。
9. 通过@value注解来读取application.properties里面的配置
10. @Configuration标注在类上,相当于把该类作为spring的xml配置文件中的<beans>,作用 为:配置spring容器(应用上下文)
11. @Bean标注在方法上(返回某个实例的方法),等价于spring的xml配置文件中的<bean>,作用 为:注册bean对象
注:
(1)、@Bean注解在返回实例的方法上,如果未通过@Bean指定bean的名称,则默认与标注的方法名相同;
(2)、@Bean注解默认作用域为单例singleton作用域,可通过@Scope(“prototype”)设置为原型作用域;
五、springBoot的核心注解
核心注解@SpringBootApplication,是标注在启动类里面的。
虽然定义使用了多个Annotation进行了原信息标注,但实际上重要的只有三个Annotation:
@Configuration(@SpringBootConfiguration点开查看发现里面还是应用了
@Configuration)
@EnableAutoConfiguration
@ComponentScan
1、@ComponentScan
扫描根目录下的配置信息,功能其实就是自动扫描并加载符合条件的组件
2、@EnableAutoConfiguration 标记配置类
3、而@EnableAutoConfiguration也是借助@Import的帮助,将所有符合自动配置条件的bean定义 加载到IoC容器。
符合特定场景:1)bean 必须放在springFactory文件下
2)必须有@EnableAutoConfiguration 这么个key,同时把配置类放在key下面
3)配置类必须加上@Configuration注解
两个比较重要的注解:
@AutoConfigurationPackage:自动配置包
@Import: 导入自动配置的组件
1)@AutoConfigurationPackage
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
register(registry, new PackageImport(metadata).getPackageName());
}
}
它其实是注册了一个Bean的定义。
new PackageImport(metadata).getPackageName(),它其实返回了当前主程序类的 同级以及子级的包组件。这也就是为什么,我们要把DemoApplication放在项目的最高级中。
2) @Import({AutoConfigurationImportSelector.class})
@Import 收集符合自定义条件配置的bean(spring factory)
类加载器:根加载器、扩展加载器、app加载器
总结一下:配置类交给IOC容器去处理,相关的配置key value 形式,通过AutoConfigurationImportSelector 类里面的selectImports扫描加载,通过beanClassLoader拿到定义的规范。做解析、实例化后返回。
4、自动配置幕后英雄:SpringFactoriesLoader详解
借助于Spring框架原有的一个工具类:SpringFactoriesLoader的支持,
@EnableAutoConfiguration可以智能的自动配置功效才得以大功告成!
SpringFactoriesLoader属于Spring框架私有的一种扩展方案,其主要功能就是从指定的配置文件 META-INF/spring.factories加载配置。
public abstract class SpringFactoriesLoader {
//...
public static <T> List<T> loadFactories(Class<T> factoryClass, ClassLoader
classLoader) {
...
}
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader
classLoader) {
....
}
}
配合@EnableAutoConfiguration使用的话,它更多是提供一种配置查找的功能支持,即根据 @EnableAutoConfiguration的完整类名
org.springframework.boot.autoconfigure.EnableAutoConfiguration作为查找的Key,获取对应的 一组@Configuration类
所以,@EnableAutoConfiguration自动配置的过程就变成了:从classpath中搜寻所有的META- INF/spring.factories配置文件,并将其中
org.springframework.boot.autoconfigure.EnableautoConfiguration对应的配置项通过反射 (Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。
六、springBoot的启动原理
New springApplication
1、简单赋值,赋值 resourceLoader
2、拿到主启动类的信息
3、判断应用类型
4、初始化initializers ApplicationContextInitializer key对应的value,通过反射做一个实例化
5、ApplicationListener key对应的value,通过反射做一个实例化。
6、查找main方法
run方法
StopWatch stopWatch = new StopWatch();//统计运行时间
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();//异常
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);//准备环境
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);//打印banner
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);//实例化
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
七、springBoot启动
AutoConfigurationImportSelector借助spring框架原有的一个工具类SpringFactoriesLoader的支持,
@EnableAutoConfiguration可以智能地完成自动配置。
八、自定义starter
SpringBoot中的starter是一种非常重要的机制,能够抛弃以前繁杂的配置,将其统一集成进
starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启
动相应的默认配置。starter让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。
SpringBoot会自动通过classpath路径下的类发现需要的Bean,并注册进IOC容器。SpringBoot提供了针对日常企业应用研发各种场景的spring-boot-starter依赖模块。所有这些依赖模块都遵循着约定
成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。
为什么要自定义starter
在我们的日常开发工作中,经常会有一些独立于业务之外的配置模块,我们经常将其放到一个特定的
包下,然后如果另一个工程需要复用这块功能的时候,需要将代码硬拷贝到另一个工程,重新集成一
遍,麻烦至极。如果我们将这些可独立于业务代码之外的功配置模块封装成一个个starter,复用的时
候只需要将其在pom中引用依赖即可,SpringBoot为我们完成自动装配,简直不要太爽。
自定义starter的命名规则
SpringBoot提供的starter以spring-boot-starter-xxx的方式命名的。官方建议自定义的starter使用
xxx-spring-boot-starter命名规则。以区分SpringBoot生态提供的starter。