springboot
1.概念
官方文档https://docs.spring.io/spring-boot/docs/1.5.17.RELEASE/reference/htmlsingle/#boot-features-external-config
2.自动配置
2.1自动配置启动(源码分析)
@SpringBootApplication//启动类注解
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration//配置
@EnableAutoConfiguration//自动加载
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration//配置类
public @interface SpringBootConfiguration {
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage//自动加载的包
@Import({EnableAutoConfigurationImportSelector.class})//加载EnableAutoConfigurationImportSelector
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class})//加载Registrar
public @interface AutoConfigurationPackage {
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
Registrar() {
}
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
}//(new AutoConfigurationPackages.PackageImport(metadata)).getPackageName()扫描的包,可以打断点使用计算查看
public class EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector {
public class AutoConfigurationImportSelector implements DeferredImportSelector, ..//这个可以看官网spring的注解,对于这个类有相关介绍 .... public String[] selectImports(AnnotationMetadata annotationMetadata) List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
try {//读取的文件的位置
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());

其中例如有HttpEncodingAutoConfiguration编码的处理类,该类所有在配置文件中能配置的属性都是在xxxxProperties类中封装
总结:
1》@SpringBootApplication的main方法运行时自动扫描的包为:(new AutoConfigurationPackages.PackageImport(metadata)).getPackageName()扫描的包,可以打断点使用计算查看,默认为同包下
2》@SpringBootApplication会加载META-INF/spring.factories文件,将该配置文件中的配置载入到Spring容器。每种具有相应的xxxxProperties与之对应
2.2 @ConfigurationProperties
配置该注解后会出现如下
![]()
解决方法
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
添加后如下,添加后的作用增加书写配置的提示功能

功能:自动注入相应的属性。并具备支持jsr3.3功能
例如:配置数据源
DataSourceAutoConfiguration自动配置类,对应的自动的properties为DataSourceProperties。
我们看DataSourceProperties类如下

所以相应的配置为:
spring.datasource.属性
总结:@ConfigurationProperties具有自动注解的功能
备注:其他注解
@Conditional派生注解//指定的条件成立才生效,否则无效

我们可以在配置文件中添加debug=true;来让控制台打印自动配置报告,这样可以很方便的知道哪些自动配置类生效;
2.3依赖的基本讲解
例如如下
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.17.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>//web依赖及启动
</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>
在父依赖中我们可以看到这样的一个依赖,里面有相应的的版本和依赖
<groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>1.5.17.RELEASE</version>
在配置文件中我们可以看到相应的配置的顶级依赖
假如我们需要添加向相应的依赖,那么可以参考官网添加相应的组件,如下

2.4 可自动加载的配置文件类型及位置及顺序及书写规范及使用
1)可自动加载的配置文件类型

2)加载的位置及顺序
a)优先级由高到低
file:./config/
file:./
classpath:/config/
classpath:/
b)现在加载的配置优先级高,高优先级的配置会覆盖低优先级的配置,同一文件夹下,文件顺序靠前的优先级高
c)配置外的加载顺序,,优先级由高到低,也可以使用如下方式
命令行参数
所有的配置都可以在命令行上进行指定
java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc,多个配置用空格分开; --配置项=值
来自java:comp/env的JNDI属性
Java系统属性(System.getProperties())
操作系统环境变量
RandomValuePropertySource配置的random.*属性值
优先加载带profile
jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
jar包外部的application.properties或application.yml(不带spring.profile)配置文件
jar包内部的application.properties或application.yml(不带spring.profile)配置文件
总结:所有的配置都可以在命令行上进行指定优先级是最高的,然后是系统环境类配置,然后是外部的application-{profile},然后是内部的application-{profile},然后是外部的application,然后是内部的application
3)书写规范
a)yml文件概念
YAML A Markup Language:是一个标记语言,YAML isn't Markup Language:不是一个标记语言;YAML:以数据为中心,比json、xml等更适合做配置文件;
b)规范
属性和值也是大小写敏感
字面量:普通的值(数字,字符串,布尔)
直接写
字符串默认不用加上单引号或者双引号;
"":双引号;不会转义字符串里面的特殊字符;
'':单引号;会转义特殊字符
对象、Map(属性和值)(键值对):
k: v:的方式书写属性和值的关系;例如//注意空格:后有空格
map: name: 张三 age: 23
行内写法:map: {name: 张三,age: 23}
数组(List、Set):
用- 值表示数组中的一个元素//在-后又空格
例如
pets:
‐ dog
‐ cat
行内写法 pets: [dog,cat]
4) 使用
map: {name: 张三, age: 23}
@Component
@ConfigurationProperties(prefix = "map")//会提示红色,需要导入提示jar,当然不导入也可以运行
public class Person {
<dependency>//提示依赖
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
备注:
yml书写是要注意层级关系,yml是依靠空格来控制层级关系的,对齐表示同一层级,靠后表示子层级,类似xml。
![]()
占位符
例如${random.value}、${random.int}、${random.long},person.last‐name=张三${random.uuid}
3.@Value获取值和@ConfigurationProperties获取值区别

4.@PropertySource&@ImportResource的区别
@PropertySource:加载指定的配置文件,配置中的内容不会生效,需要使用例如spel的方式获取
@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效;
备注:在配置文件中可以添加随机占位符,${random.xxx}
5.@Profile
server: port: 8081 spring: profiles: active: prod #激活prod 端口变为8084 多配置选择 ‐‐‐ #分块 server: port: 8083 spring: profiles: dev ‐‐‐ server: port: 8084 spring: profiles: prod #指定属于哪个环境
激活的方式除了上述还有如下方式
配置文件中指定 spring.profiles.active=dev需要配合application-{profile}.properties/yml方式使用,默认加载的是application.properties的配置在其中通过spring.profiles.active=dev指定 命令行 java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev; 可以直接在测试的时候,配置传入命令行参数
虚拟机参数 -Dspring.profiles.active=dev
5.web中的使用
5.1静态资源的访问(WebMvcAutoConfiguration)
webjars:可以以jar包的方式引入静态资源;http://www.webjars.org/
<!‐‐例如 :引入jquery‐‐> <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.3.1</version> </dependency>
所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源;
"/**" 访问当前项目的任何资源,都去(静态资源的文件夹)找映射(源码中就是采用的/**),所以也可以放入如下位置
"classpath:/META‐INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"
private static final String[] SERVLET_RESOURCE_LOCATIONS = new String[]{"/"};
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/",
"classpath:/public/"};
也可以自己指定文件位置,spring.resources.static-locations=值的方式指定多个多个位置,用逗号隔开,但是默认位置就不在生效
默认页面的加载欢迎页; 静态资源文件夹下的所有index.html页面;
private WelcomePageHandlerMapping(Resource welcomePage, String staticPathPattern) {
if (welcomePage != null && "/**".equals(staticPathPattern)) {
logger.info("Adding welcome page: " + welcomePage);
ParameterizableViewController controller = new ParameterizableViewController();
controller.setViewName("forward:index.html");
this.setRootHandler(controller);
this.setOrder(0);
}
}
图标所有的 **/favicon.ico 都是在静态资源文件下找;
@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(-2147483647);
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", this.faviconRequestHandler()));
return mapping;
}
综上:
5.2 thymeleaf(官方推荐支持thymeleaf,不支持jsp)(官方文档https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.pdf)
引入依赖(已经有了相应的管理)
![]()
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<-- 不需要写版本,假如想更改版本,可以这样写!-->
<properties> <thymeleaf.version>3.0.9.RELEASE</thymeleaf.version> <!‐‐ 布局功能的支持程序 thymeleaf3主程序 layout2以上版本 ‐‐> <!‐‐ thymeleaf2 layout1‐‐> <thymeleaf‐layout‐dialect.version>3.0.9</thymeleaf‐layout‐dialect.version> </properties>
配置thymeleaf的默认解析,前缀为classpath:/templates/,后缀为.html
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
基本使用:

其他(可以去官网看示例)
Simple expressions:(表达式语法)
Variable Expressions: ${...}:获取变量值;OGNL;
1)、获取对象的属性、调用方法
2)、使用内置的基本对象:
#ctx : the context object.
#vars: the context variables.
#locale : the context locale.
#request : (only in Web Contexts) the HttpServletRequest object.
#response : (only in Web Contexts) the HttpServletResponse object.
#session : (only in Web Contexts) the HttpSession object.
#servletContext : (only in Web Contexts) the ServletContext object.
${session.foo}
3)、内置的一些工具对象:
#execInfo : information about the template being processed.
#messages : methods for obtaining externalized messages inside variables expressions, in the
same way as they would be obtained using #{…} syntax.
#uris : methods for escaping parts of URLs/URIs
#conversions : methods for executing the configured conversion service (if any).
#dates : methods for java.util.Date objects: formatting, component extraction, etc.
#calendars : analogous to #dates , but for java.util.Calendar objects.
#numbers : methods for formatting numeric objects.
#strings : methods for String objects: contains, startsWith, prepending/appending, etc.
#objects : methods for objects in general.
#bools : methods for boolean evaluation.
#arrays : methods for arrays.
#lists : methods for lists.
#sets : methods for sets.
#maps : methods for maps.
#aggregates : methods for creating aggregates on arrays or collections.
#ids : methods for dealing with id attributes that might be repeated (for example, as a
result of an iteration).
Selection Variable Expressions: *{...}:选择表达式:和${}在功能上是一样;
补充:配合 th:object="${session.user}:
<div th:object="${session.user}">
<p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
</div>
Message Expressions: #{...}:获取国际化内容
Link URL Expressions: @{...}:定义URL;
@{/order/process(execId=${execId},execType='FAST')}
Fragment Expressions: ~{...}:片段引用表达式
<div th:insert="~{commons :: main}">...</div>
Literals(字面量)
Text literals: 'one text' , 'Another one!' ,…
Number literals: 0 , 34 , 3.0 , 12.3 ,…
Boolean literals: true , false
Null literal: null
Literal tokens: one , sometext , main ,…
Text operations:(文本操作)
String concatenation: +
Literal substitutions: |The name is ${name}|
Arithmetic operations:(数学运算)
Binary operators: + , ‐ , * , / , %
Minus sign (unary operator): ‐
Boolean operations:(布尔运算)
Binary operators: and , or
Boolean negation (unary operator): ! , not
Comparisons and equality:(比较运算)
Comparators: > , < , >= , <= ( gt , lt , ge , le )
Equality operators: == , != ( eq , ne )
Conditional operators:条件运算(三元运算符)
If‐then: (if) ? (then)
If‐then‐else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
Special tokens:
No‐Operation: _
[[]]会转义特殊字符 [()]不会特殊转义
6.springmvc
自动配置
Converter , GenericConverter , Formatter beans 视图解析器ContentNegotiatingViewResolver and BeanNameViewResolver beans 静态资源处理等
具体可以查看

拓展的配置
<mvc:view‐controller path="/hello" view‐name="success"/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/hello"/>
<bean></bean>
</mvc:interceptor>
</mvc:interceptors>
自定义配置
@Configuration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
自己添加功能可以实现WebMvcConfigurerAdapter,也就spring注解的中的一些接口实现
//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// super.addViewControllers(registry);
//浏览器发送 /index请求来到 success
registry.addViewController("/index").setViewName("success");
}
}
当使用@EnableWebMvc自动配置就失效
原因
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
WebMvcConfigurerAdapter.class })
//容器中没有这个组件的时候,这个自动配置类才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
转发重定向前后缀处理:自定拼串
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
国际化
@ConfigurationProperties(
prefix = "spring.messages"
)
public class MessageSourceAutoConfiguration {
private static final Resource[] NO_RESOURCES = new Resource[0];
private String basename = "messages";
默认的就是根据请求头带来的区域信息获取Locale进行国际化
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
if (this.mvcProperties
.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
}
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
点击链接切换国际化
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
String l = request.getParameter("l");
Locale locale = Locale.getDefault();
if(!StringUtils.isEmpty(l)){
String[] split = l.split("_");
locale = new Locale(split[0],split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale
locale) {
}
}
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
例如
login.remember=记住我
<input type="checkbox" value="remember-me"> [[#{login.remember}]]
spring.messages.basename=i18n.index
禁用thymeleaf模板的缓存,ctrl+f9可以重写编译便于开发
spring.thymeleaf.cache=false
th:if
<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
登录检查
public class LoginHandlerInterceptor implements HandlerInterceptor {
//目标方法执行之前
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
Object user = request.getSession().getAttribute("loginUser");
if(user == null){
//未登陆,返回登陆页面
request.setAttribute("msg","没有权限请先登陆");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else{
//已登陆,放行请求
return true;
}
}
注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//super.addInterceptors(registry);
//静态资源; *.css , *.js SpringBoot已经做好了静态资源映射
registry.addInterceptor(new
LoginHandlerInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login");
}
};
restful

thymeleaf引入片段
抽取公共片段
<div th:fragment="copy">
© 2018 The Good Thymes Virtual Grocery
</div>
引入公共片段
<div th:insert="~{footer :: copy}"></div>
~{templatename::selector}:模板名::选择器
~{templatename::fragmentname}:模板名::片段名
默认效果:
insert的公共片段在div标签中
如果使用th:insert等属性进行引入,可以不用写~{}:
行内写法可以加上:[[~{}]];[(~{})];
th:insert:将公共片段整个插入到声明引入的元素中
th:replace:将声明引入的元素替换为公共片段
th:include:将被引入的片段的内容包含进这个标签中
例如
<footer th:fragment="copy"> © 2018 The Good Thymes Virtual Grocery </footer> 引入方式 <div th:insert="footer :: copy"></div> <div th:replace="footer :: copy"></div> <div th:include="footer :: copy"></div> 效果 <div> <footer> © 2011 The Good Thymes Virtual Grocery </footer> </div> <footer> © 2011 The Good Thymes Virtual Grocery </footer> <div> © 2011 The Good Thymes Virtual Grocery </div>
日期格式化
public Formatter<Date> dateFormatter() {
return new DateFormatter(this.mvcProperties.getDateFormat());
}
默认格式
修改
spring.mvc.date-format=yyyy-MM-dd
定义了的格式类型
static {
Map<ISO, String> formats = new EnumMap(ISO.class);
formats.put(ISO.DATE, "yyyy-MM-dd");
formats.put(ISO.TIME, "HH:mm:ss.SSSZ");
formats.put(ISO.DATE_TIME, "yyyy-MM-dd'T'HH:mm:ss.SSSZ");
ISO_PATTERNS = Collections.unmodifiableMap(formats);
}
错误处理机制
根据不同的头信息accept返回相应的值,html/text返回的是页面,*/*返回的是json数据
原理:
可以参照ErrorMvcAutoConfiguration;错误处理的自动配置;
给容器中添加了以下组件
DefaultErrorAttributes:
@Override
public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes,
boolean includeStackTrace) {
Map<String, Object> errorAttributes = new LinkedHashMap<String, Object>();
errorAttributes.put("timestamp", new Date());
addStatus(errorAttributes, requestAttributes);
addErrorDetails(errorAttributes, requestAttributes, includeStackTrace);
addPath(errorAttributes, requestAttributes);
return errorAttributes;
}
BasicErrorController:处理默认/error请求,根据不同的accept,返回相应的值
ErrorPageCustomizer
@Value("${error.path:/error}")
private String path = "/error"; 系统出现错误以后来到error请求进行处理;(web.xml注册的错误页面规则)
DefaultErrorViewResolver:
static {
Map<Series, String> views = new HashMap();
views.put(Series.CLIENT_ERROR, "4xx");
views.put(Series.SERVER_ERROR, "5xx");
SERIES_VIEWS = Collections.unmodifiableMap(views);
}
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status,
Map<String, Object> model) {
ModelAndView modelAndView = resolve(String.valueOf(status), model);
if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
}
return modelAndView;
}
private ModelAndView resolve(String viewName, Map<String, Object> model) {
//默认SpringBoot可以去找到一个页面? error/404
String errorViewName = "error/" + viewName;
//模板引擎可以解析这个页面地址就用模板引擎解析
TemplateAvailabilityProvider provider = this.templateAvailabilityProviders
.getProvider(errorViewName, this.applicationContext);
if (provider != null) {
//模板引擎可用的情况下返回到errorViewName指定的视图地址
return new ModelAndView(errorViewName, model);
}
//模板引擎不可用,就在静态资源文件夹下找errorViewName对应的页面 error/404.html
return resolveResource(errorViewName, model);
}
thymeleaf模板能获取的信息;
timestamp:时间戳
status:状态码
error:错误提示
exception:异常对象
message:异常消息
errors:JSR303数据校验的错误都在这里
备注:假如以上页面都没有那么返回默认的页面
另外一种处理异常的方式,这里是转发到error页面来处理,进行根据不同的头信息accept返回相应的值,html/text返回的是页面,*/*返回的是json数据
@ExceptionHandler(UserNotExistException.class)
public String handleException(Exception e, HttpServletRequest request){
Map<String,Object> map = new HashMap<>();
//传入我们自己的错误状态码 4xx 5xx,否则就不会进入定制错误页面的解析流程
/**
* Integer statusCode = (Integer) request
.getAttribute("javax.servlet.error.status_code");
*/
request.setAttribute("javax.servlet.error.status_code",500);
map.put("code","user.notexist");
map.put("message",e.getMessage());
request.setAttribute("ext",map)//将map的数据放入,其实这个可要可不要
//转发到/error
return "forward:/error";
}
以上定义存在自定义数据不能携带的问题
出现错误以后,会来到/error请求,会被BasicErrorController处理,响应出去可以获取的数据是由getErrorAttributes得到的(是AbstractErrorController(ErrorController)规定的方法);
1、完全来编写一个ErrorController的实现类【或者是编写AbstractErrorController的子类】,放在容器中;
2、页面上能用的数据,或者是json返回能用的数据都是通过errorAttributes.getErrorAttributes得到;容器中DefaultErrorAttributes.getErrorAttributes();默认进行数据处理的;
自定义ErrorAttributes
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes,
boolean includeStackTrace) {
Map<String, Object> map = super.getErrorAttributes(requestAttributes,
includeStackTrace);
Map ext=requestAttributes.getAttribute("ext",0);//上述放入在request中的ext
map.put("ext",ext)
return map; //这样就将上述的数据携带出去,还可以自定义的在map中添加属性
}
}
7 与servlet之间的配合

设置相关属性
配置文件方式
server.port=8082 server.context‐path=/test server.tomcat.uri‐encoding=UTF‐8
另一种方式
@Bean //一定要将这个定制器加入到容器中
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
return new EmbeddedServletContainerCustomizer() {
//定制嵌入式的Servlet容器相关的规则
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.setPort(8083);
}
};
}
备注:
SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;
在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置
在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置
三大组件的使用
ServletRegistrationBean
@Bean
public ServletRegistrationBean myServlet(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new
MyServlet(),"/myServlet");
return registrationBean;
}
FilterRegistrationBean
@Bean
public FilterRegistrationBean myFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new MyFilter());
registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
return registrationBean;
}
ServletListenerRegistrationBean
@Bean
public ServletListenerRegistrationBean myListener(){
ServletListenerRegistrationBean<MyListener> registrationBean = new
ServletListenerRegistrationBean<>(new MyListener());
return registrationBean;
}
8. 外置的Servlet容器:外面安装Tomcat---应用war包的方式打包;
必须创建一个war项目;(利用idea创建好目录结构)
将嵌入式的Tomcat指定为provided;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐tomcat</artifactId>
<scope>provided</scope>
</dependency>
必须编写一个SpringBootServletInitializer的子类,并调用configure方法
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
//传入SpringBoot应用的主程序
return application.sources(SpringBoot04WebJspApplication.class);
}
}
启动服务器就可以使用
9 jdbc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql‐connector‐java</artifactId>
<scope>runtime</scope>
</dependency>
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://192.168.15.22:3306/jdbc
driver‐class‐name: com.mysql.jdbc.Driver
自动配置原理:
org.springframework.boot.autoconfigure.jdbc:
参考DataSourceConfiguration,根据配置创建数据源,默认使用Tomcat连接池;可以使用spring.datasource.type指定自定义的数据源类型;
SpringBoot默认可以支持:org.apache.tomcat.jdbc.pool.DataSource、HikariDataSource、BasicDataSource
自定义数据源类型
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type")
static class Generic {
@Bean
public DataSource dataSource(DataSourceProperties properties) {
//使用DataSourceBuilder创建数据源,利用反射创建响应type的数据源,并且绑定相关属性
return properties.initializeDataSourceBuilder().build();
}
}
DataSourceInitializer:ApplicationListener
runSchemaScripts();运行建表语句;
runDataScripts();运行插入数据的sql语句;
默认只需要将文件命名为:
schema‐*.sql、data‐*.sql
默认规则:schema.sql,schema‐all.sql;
可以使用
schema:
classpath:department.sql //指定位置
整合Druid数据源
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://192.168.15.22:3306/jdbc
driver‐class‐name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")//yml的前缀spring.datasource,导入资源
@Bean
public DataSource druid(){
return new DruidDataSource();
}
//配置Druid的监控
//1、配置一个管理后台的Servlet
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(),
"/druid/*");
Map<String,String> initParams = new HashMap<>();
initParams.put("loginUsername","admin");
initParams.put("loginPassword","123456");
initParams.put("allow","");//默认就是允许所有访问
initParams.put("deny","192.168.15.21");
bean.setInitParameters(initParams);
return bean;
}
//2、配置一个web监控的filter
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map<String,String> initParams = new HashMap<>();
initParams.put("exclusions","*.js,*.css,/druid/*");
bean.setInitParameters(initParams);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}

浙公网安备 33010602011771号