springboot如何开启自动配置
1、main方法所在类的@SpringBootApplication注解
@SpringBootApplication <-----------------注解
public class SpringbootQuickApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootQuickApplication.class,args);
}
}
2、点进去注解类上有一个@EnableAutoConfiguration
@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}
)}
)
3、点进注解类上有一个注解
@Import{AutoConfigurationImportSelector.class}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
在AutoConfigurationImportSelector类中会执行getCandidateConfigurations(AnnotationMetadata metadata,AnnotationAttributes attributes)方法里面有一行:
List configurations = SpringFactoriesLoader.loadFactoryNames(
getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
这里就会扫描具有MEAT-INF/spring.factories文件的jar包,得到所有的配置类:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames
(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
return configurations;
}
4、找到spring.factories文件的内容看下
4.1、spring.factories自动注入的内容
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
4.2、解释几个注解
@SpringBootApplication:启动stringboot环境
@ComponentScan:配置包扫描
@ImportResource:引入自定义配置文件
springboot如何处理异常的
1 、自定义错误页面
如 果 我 们 需 要 将 所 有 的 异 常 同 一 跳 转 到 自 定 义 的 错 误 页 面
需 要 再src/main/resources/templates 目录下创建 error.html 页面。注意:名称必须叫 error
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>错误提示页面</title>
</head>
<body>
错了 我不giao了
<span th:text="${exception}"></span>
</body>
</html>
2、@ExceptionHandle 注解处理异常
上一种方法不管发生什么异常,都只能跳转到一个页面,颗粒度太大而这一种方式可以实现对不同的异常做不同的处理
@Controller
public class DemoController {
@RequestMapping("/show")
public String showInfo(){
String str = null;
str.length();
return "index";
}
@RequestMapping("/show2")
public String showInfo2(){
int a = 10/0;
return "index";
}
// 算数错误
@ExceptionHandler(value={java.lang.ArithmeticException.class})
public ModelAndView arithmeticExceptionHandler(Exception e){
ModelAndView mv = new ModelAndView();
mv.addObject("error", e.toString());
mv.setViewName("error1");
return mv;
}
//空指针异常
@ExceptionHandler(value={java.lang.NullPointerException.class})
public ModelAndView nullPointerExceptionHandler(Exception e){
ModelAndView mv = new ModelAndView();
mv.addObject("error", e.toString());
mv.setViewName("error2");
return mv;
}
页面1
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>错误提示页面-ArithmeticException</title>
</head>
<body>
出错了,请与管理员联系。。。
<span th:text="${error}"></span>
</body>
</html>
页面2
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>错误提示页面-NullPointerException</title>
</head>
<body>
<span th:text="${error}"></span>
</body>
</html>
3、@ControllerAdvice+@ExceptionHandler 注解处理异常
上一种方式必须要在每一个Controler里面重复写异常处理代码,代码复用性太差,这一种方法可以实现异常的全局处理。需要创建一个能够处理异常的全局异常类。在该类上需要添加@ControllerAdvice 注解
@ControllerAdvice
public class GlobalException {
//java.lang.ArithmeticException
@ExceptionHandler(value={java.lang.ArithmeticException.class})
public ModelAndView arithmeticExceptionHandler(Exception e){
ModelAndView mv = new ModelAndView();
mv.addObject("error", e.toString());
mv.setViewName("error1");
return mv;
}
//java.lang.NullPointerException
ExceptionHandler(value={java.lang.NullPointerException.class})
public ModelAndView nullPointerExceptionHandler(Exception e){
ModelAndView mv = new ModelAndView();
mv.addObject("error", e.toString());
mv.setViewName("error2");
return mv;
}
}
}
4、配置 SimpleMappingExceptionResolver 处理异常
//通过 SimpleMappingExceptionResolver 做全局异常处理
@Configuration
public class GlobalException {
//该方法必须要有返回值。返回值类型必须是:SimpleMappingExceptionResolver
@Bean
public SimpleMappingExceptionResolver
getSimpleMappingExceptionResolver(){
SimpleMappingExceptionResolver resolver = new
SimpleMappingExceptionResolver();
Properties mappings = new Properties();
/**
* 参数一:异常的类型,注意必须是异常类型的全名
* 参数二:视图名称
*/
mappings.put("java.lang.ArithmeticException", "error1");
mappings.put("java.lang.NullPointerException","error2");
//设置异常与视图映射信息的
resolver.setExceptionMappings(mappings);
return resolver;
}
}
5、自定义 HandlerExceptionResolver 类处理异常
/**
* 通过实现 HandlerExceptionResolver 接口做全局异常处理
*/
@Configuration
public class GlobalException implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler,Exception ex) {
ModelAndView mv = new ModelAndView();
//判断不同异常类型,做不同视图跳转
if(ex instanceof ArithmeticException){
mv.setViewName("error1");
}
if(ex instanceof NullPointerException){
mv.setViewName("error2");
}
mv.addObject("error", ex.toString());
return mv;
}
}
在springboot中,如何使用拦截器?
1、实现拦截器
public class InterceptorDemo extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
StringBuffer requestURL = httpServletRequest.getRequestURL();
System.out.println("前置拦截器1 preHandle: 请求的uri为:"+requestURL.toString());
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器1 postHandle: ");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("拦截器1 afterCompletion: ");
}
}
2、注册拦截器
@Configuration
public class InterceptorConfig implements WebMvcConfigurer{
//注册自定义拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new InterceptorDemo2()).addPathPatterns("/**");
registry.addInterceptor(new InterceptorDemo()).addPathPatterns("/**");
}
}
在springboot中,如何扩展springmvc的功能
@Configuration <-----注解
public class WebMVCConfig implements WebMvcConfigurer { <----实现WebMvcConfigurer
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/index").setViewName("index");
//定义跳转到主页面的视图
registry.addViewController("/dashboard.html").setViewName("dashboard");
}
}