初始化项目
https://start.spring.io/
配置启动
获取 context
1 2 3
| public static void main(String[] args) { ApplicationContext context = SpringApplication.run(SpringDemoApplication.class, args); }
|
三种启动写法,并做一些启动设置
- SpringApplication.run
- new SpringApplication()
1 2 3 4 5 6
| public static void main(String[] args) {
SpringApplication app = new SpringApplication(SpringDemoApplication.class); app.setBannerMode(Banner.Mode.OFF); ApplicationContext context = app.run(args); }
|
- new SpringApplicationBuilder()
1 2 3 4 5 6
| public static void main(String[] args) { ApplicationContext run = new SpringApplicationBuilder() .sources(SpringDemoApplication.class) .bannerMode(Banner.Mode.CONSOLE) .run(args); }
|
替换 Logo
resources/banner.txt
配置文件中指定启动的类
1
| spring.main.sources=com.koory1st.spring_demo.SpringDemoApplication
|
启动后回调
1 2 3 4 5 6
| @SpringBootApplication public class SpringDemoApplication implements CommandLineRunner { @Override public void run(String... args) throws Exception { } }
|
1 2 3 4 5 6
| @SpringBootApplication public class SpringDemoApplication implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { } }
|
配置启动类型
可配置的值:none, web,
1
| spring.main.web-application-type=servlet
|
web 工程启动顺序
- 启动 ioc 容器
- 启动内嵌的 tomcat
自动化配置
Springboot 的自动化配置是在org.springframework.boot.autoconfigure实现的。大部分的预先配置都是在META-INF/spring.factories这里配置的。
禁止自动化配置
1
| @SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
|
1
| spring.autoconfigure.exclude=
|
bean
添加 bean
- @Component()
- @Configuration(其实也是@Component)
- @Configuration + @Bean
- @Import(MyBean.class)
- @Configuration + @ComponentScan
- @ImportResource(locations = “classpath:applicationContext.xml”)
延迟初始化 Bean
全局延迟初始化
1
| spring.main.lazy-initialization=true
|
1 2 3 4 5 6 7
| public static void main(String[] args) { ApplicationContext run = new SpringApplicationBuilder() .lazyInitialization(true) .sources(SpringDemoApplication.class) .bannerMode(Banner.Mode.CONSOLE) .run(args); }
|
在全局都是延迟化的情况下,使用@Lazy(false)注解使某个 Bean 不延迟初始化。
敏感信息加密
一个三方类库 jasypt
gradle
1
| implementation group: 'com.github.ulisesbocchio', name: 'jasypt-spring-boot-starter', version: '3.0.3'
|
maven
1 2 3 4 5
| <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.3</version> </dependency>
|
配置文件需要配置一个密码
1
| jasypt.encryptor.password=1234
|
1 2 3 4 5 6 7 8 9 10 11
| @Autowired private StringEncryptor stringEncryptor;
@Test public void encryptString() { String abc = stringEncryptor.encrypt("abc"); System.out.println("abc = " + abc);
String decrypt = stringEncryptor.decrypt(abc); System.out.println("decrypt = " + decrypt); }
|
之后,就可以使用以下的方式配置了,jasypt 会解密
1
| name=ENV(VAHGUMgVllLkHelXYfCa2zFsMs/OziuhGAovjSh7PTx+KBSESpcAs49a73w640LQ)
|
跨域 CORS
1 2 3 4 5 6 7 8 9 10 11
| @Configuration public class MyConfig { public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/web/**"); } }; } }
|
1 2 3 4 5 6 7
| @Configuration public class MyConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/web/**"); } }
|
静态资源
默认位置
- /static
- /public
- /resoures
- /META-INF/resources
指定
1
| spring.resources.static-locations=classpath:/my-static
|
读取配置文件
@Value
@ConfigurationProperties(prefix = “my”)
Environment
1 2 3 4 5
| @Autowired private Environment env;
env.getProperty("my.abc");
|
有嵌套结构,使用静态内部类读取
参考
1
| org.springframework.boot.autoconfigure.web.ServerProperties
|
线程池异步调用 @Async
配置上添加 @EnableAsync
1 2
| @EnableAsync @Configuration
|
方法上添加 @Async
1 2 3 4
| @Async public void sendMsg() { log.info("sendMsg" + Thread.currentThread().getName()); }
|
注意
不能自类调用Async方法
不能自类调用Async方法,因为要用Spring代理后的bean,若必须要在自己类里使用,需要获取bean后再做调用。
返回值只能是 void 或者 Future<>
自定义线程池
参考How To Do @Async in Spring
1 2 3 4 5 6 7 8 9
| @Configuration @EnableAsync public class SpringAsyncConfig { @Bean(name = "threadPoolTaskExecutor") public Executor threadPoolTaskExecutor() { return new ThreadPoolTaskExecutor(); } }
|
1 2 3 4 5
| @Async("threadPoolTaskExecutor") public void asyncMethodWithConfiguredExecutor() { System.out.println("Execute method with configured executor - " + Thread.currentThread().getName()); }
|
全局覆盖线程池
参考How To Do @Async in Spring
1 2 3 4 5 6 7 8 9
| @Configuration @EnableAsync public class SpringAsyncConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { return new ThreadPoolTaskExecutor(); } }
|
异常处理
参考How To Do @Async in Spring
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override public void handleUncaughtException( Throwable throwable, Method method, Object... obj) { System.out.println("Exception message - " + throwable.getMessage()); System.out.println("Method name - " + method.getName()); for (Object param : obj) { System.out.println("Parameter value - " + param); } } }
|
或者
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Configuration @EnableAsync public class SpringAsyncConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { return new ThreadPoolTaskExecutor(); } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new CustomAsyncExceptionHandler(); } }
|
Websocket
1
| implementation 'org.springframework.boot:spring-boot-starter-websocket'
|