Love life, love coding, wechat search [Architecture Technology column] pay attention to this place like sharing. This article architecture technology column has been included, there are a variety of JVM, multi-threading, source code video, information and technical articles waiting for you to take.
Spring Boot series (1) : Start the SpringApplication
Spring Boot series (2) Configuration feature analysis
Spring Boot series (3) : the latest version of elegant shutdown details
Spring Boot series (4) : Log dynamic configuration details
An overview,
At present, Spring Boot has developed to 2.3.4.RELEASE, and its benefits are overwhelming online, so I will not repeat them here. To get straight to the point, there are a lot of pitfalls in upgrading from Spring Boot1.x step by step to 2.3.4. It is important to understand the features of the new version to help us avoid a lot of unnecessary trouble.
Because I have also been gay on Spring Boot technology stack component development work, recently prepared in view of the basic component part of the refactoring, so by the way, the current version of the feature from the beginning in the paramagnetic again, be review summarizes, this review introduces some characteristics of the current version, only not to narrative features, if they are interested in can @ me, I will also make a detailed analysis based on a particular piece. Like friends can follow a look, hope to help you.
Start from scratch with Application
IO/production, or spring Boot plugin for IDEA. At the end of this article, I will also drop the address of my test demo.
1. Startup Failure
If the application fails to start, Spring Boot will help us print the information about the failure in the log. For example, if I start the application using port 6080 for the second time, I will be prompted as follows
***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 6080 was already in use.
Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
Copy the code
It’s nice to have this kind of friendly prompt, and Spring Boot also provides us with more extended interface FailureAnalyzer and abstract class FailureAnalyzer that responds to it.
If we do not satisfy his default startup exception information, we can use FailureAnalyzer to do some custom development (such as printing the stack when an exception occurs, etc.).
The FailureAnalyzer extension uses SPI, so we need to create meta-INF/Spring. factories in our application to declare our implementation.
PortInUseException = PortInUseException = PortInUseException = PortInUseException = PortInUseException@ClassName LearningFailureAnalyzer
* @Author QIANGLU
* @Date 2020/9/23 9:10 下午
* @Version1.0 * /
public class LearningFailureAnalyzer extends AbstractFailureAnalyzer<PortInUseException> {
private static final Logger LOGGER = LoggerFactory.getLogger(LearningFailureAnalyzer.class);
@Override
protected FailureAnalysis analyze(Throwable rootFailure, PortInUseException cause) {
LOGGER.error("Something's wrong with me. Wow, chuck, chuck, chuck.");
return new FailureAnalysis("Port:" +cause.getPort()+"Occupied",cause.getMessage(),rootFailure); }}// The second step is to create a meta-INF /spring.factories like this
org.springframework.boot.diagnostics.FailureAnalyzer=\
com.qianglu.chapter1.failure.LearningFailureAnalyzer
// Start the application twice and find that the printed information is what we need* * * * * * * * * * * * * * * * * * * * * * * * * * * the APPLICATION FAILED TO START * * * * * * * * * * * * * * * * * * * * * * * * * * * Description: port:6080Occupied Action: Port6080 is already in use
Copy the code
This thing can be used in many scenarios, we think about whether there is a point of inspiration
2. Lazy Initialization
In the early days of Spring Boot, you were teased for being slow to start up, but now lazy loading is coming. By allowing your application to start lazy loading, your Beans don’t need to be created at project startup.
This can save you a lot of startup time, but there are pros and cons. Lazy loading in web applications can cause many of your Web-related beans to be lazily loaded until a request comes in.
And the official thing is, if you delay initialization, then some problems might be found later. For example, we used to have some configuration mismatches and would often report XXXbean could not be found at startup. Hey hey, now can not, the same start success, only when you use to give you off the chain, ask you afraid.
There is also the official prompt for late initialization, which can lead to a small initial JVM memory performance, but be careful to configure enough memory for future object creation (I think this is not a problem in general, do not need too much attention).
Let’s take a look at two configurations:
- Use SpringApplication to call the setLazyInitialization method
- Use the configuration spring.main.lazy-initialization=true
If you have Lazy initialization and you want to initialize a particular class, you can configure @lazy (false) to turn off Lazy loading.
3. Configure the Banner
This thing to tell the truth I do not know what to use, before we are configured with a Buddha to protect safety, entertainment is greater than the actual bar, of course, there may be no point to GET.
The configuration is also simple: place banner.txt in your classpath and specify the location of the file via the spring.banner.location configuration. Of course, there are a lot of attributes, but I don’t want to talk about encoding, GIF, version and so on.
4. Configure your SpringApplication
We usually start classes by calling SpringApplication.run directly. But if you think it’s too simple to be interesting, springApplication.run has a lot of interesting properties that you can check out, like I turned off the banner
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
Copy the code
Of course, there are many configuration properties. You can also configure SpringApplication properties using application.yml.
5. Fluent Builder API
The SpringApplicationBuilder class is available to help you create multiple levels of ApplicationContext using a stream build. SpringApplicationBuilder can help us build a hierarchy in such a way as springApplication.run
new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
Copy the code
6. Application Availability
This is about Liveness and Readiness in K8S, which have become the heart of Spring Boot.
To recap, Liveness and Readiness represent all aspects of application state in K8S.
Liveness is a health check. If Liveness fails, the application is in a faulty state and cannot be recovered. Restart the application.
The Readiness state is used to tell the application whether Readiness is ready to accept client requests. If Readiness is not ready, K8S cannot route traffic.
We can use code to monitor Readiness and do what we need to do
@Component
public class ReadinessStateExporter {
@EventListener
public void onStateChange(AvailabilityChangeEvent<ReadinessState> event) {
switch (event.getState()) {
case ACCEPTING_TRAFFIC:
// xxxxx
break;
case REFUSING_TRAFFIC:
// xxxxxx
break; }}}Copy the code
We can also change this state for dynamic degradation and isolation if the application fails and cannot be recovered, which is really cool and I suggest you give it a try
@Component public class LocalCacheVerifier { private final ApplicationEventPublisher eventPublisher; public LocalCacheVerifier(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } public void checkLocalCache() { try { //... } catch (CacheCompletelyBrokenException ex) { AvailabilityChangeEvent.publish(this.eventPublisher, ex, LivenessState.BROKEN); }}}Copy the code
Application Events and Listeners
Spring Boot’s event notification mechanism is a great decoupler, including the distributed remote notification mechanism used by Spring Cloud. This is the core of this mechanism, which adds a layer of middleware for message delivery.
Some events are triggered before the ApplicationContext is created, so in many cases you cannot declare these events using @Beans. It is best to use SpringApplication. AddListeners (…). And SpringApplicationBuilder. Listeners (…). To register the listener.
But if you’re really having trouble with these load times, a handy way to do this is to configure the SPI extension directly in meta-INF/Spring. factories with your listener, for example: org.springframework.context.ApplicationListener=com.example.project.MyListener
The order of events that will be sent at startup is described:
ApplicationStartingEvent sends an event at the start of a run
2, ApplicationEnvironmentPreparedEvent when the Environment is used in this context to send events
3, ApplicationContextInitializedEvent before all the bean definitions, ApplicationContext ready and ApplicationContextInitializers send events has been called
ApplicationPreparedEvent emits an event before the configuration is refreshed and after the bean definition is loaded
ApplicationStartedEvent refreshes the context before executing the implementation of CommandLineRunner
6, AvailabilityChangeEvent send LivenessState.CORRECT the surface application is active
ApplicationReadyEvent is sent after executing the CommandLineRunner interface
8. AvailabilityChangeEvent ReadinessState.ACCEPTING_TRAFFIC indicates that the application can access traffic
ApplicationFailedEvent Sends an application startup failure event
The above is only the event of SpringApplicationEvent, generally we do not need to operate on these, with you have to know its existence, so as not to know how to find a problem, in fact, someone else Spring Boot has been sent to you.
8. Web properties
Normally, using SpringApplication will create the ApplicationContext for us correctly. The way to determine the WebApplicationType, which is the application type, is very simple:
- If there is a use AnnotationConfigServletWebServerApplicationContext Spring MVC
- If you don’t put in Spring MVC, but Spring WebFlux exist, use AnnotationConfigReactiveWebServerApplicationContext
- Have no word with AnnotationConfigApplicationContext
- If you use both Spring MVC and Spring WebFlux WebClient, the Spring MVC suite is used by default. Unless you set SpringApplication. SetWebApplicationType (WebApplicationType) to force change.
(Accessing Application Arguments)
If you want to access SpringApplication.run(…) Parameters, you actually can inject a org. Springframework. Boot. ApplicationArguments object, ApplicationArguments this interface provides the original String [] parameters and parsed option and the option of access, On the demo:
import org.springframework.boot.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.stereotype.*;
@Component
public class MyBean {
@Autowired
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
// if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]}}Copy the code
Environment variable in the Spring the Boot also registered a CommandLinePropertySource, we can use @ Value to obtain an environment variable.
Use ApplicationRunner or CommandLineRunner
They’re also used a lot if you need to load something at startup. Both interfaces provide a run method, which will be used in springApplication.run (…). Called before execution is complete. Which of these interfaces are suitable for processing something before the application receives a request?
Here’s a usage example
import org.springframework.boot.*;
import org.springframework.stereotype.*;
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...}}Copy the code
If we define the multiple CommandLineRunner or ApplicationRunner implementation, sometimes need a Order to perform again, then you can use org. Springframework. Core. The annotation. The annotations to define the Order.
11. Application Exit
Each SpringApplication registers a shutdown hook with the JVM to ensure a normal exit. Make sure the @predestroy annotation and DisposableBean interface callbacks are executed.
. In addition, if you want to use SpringApplication exit () returns some special exit code, can realize org. Springframework. Boot. ExitCodeGenerator interface, passed to the System. The exit () to return. Such as:
@SpringBootApplication
public class ExitCodeApplication {
@Bean
public ExitCodeGenerator exitCodeGenerator(a) {
return() - >42;
}
public static void main(String[] args) { System.exit(SpringApplication.exit(SpringApplication.run(ExitCodeApplication.class, args))); }}Copy the code
The ExitCodeGenerator interface can be implemented with exceptions. When such an exception is encountered, Spring Boot returns the exit code provided by the implemented getExitCode() method
12. Admin Features
. We can use the spring application. Admin. Enabled properties to open the administrator functions. Opened it will give all your SpringApplicationAdminMXBean exposed to MBeanServer, of course, you can also use this feature to remote operation your application. But you need to understand the safety implications and don’t mess around if you don’t have to.
Third, summary
Well, it is too late today, I will write this first, in fact, these contents of the official write are clearly plain, but their own masturbation is still very cool, very comfortable. In fact, in the course of masturbating you will combine your actual knowledge points for some thinking, the new features will also give you a lot of future basic design inspiration. I hope you have more time and energy, at least when I need to know that there is such a thing, there is a direction.
Love life, love coding, wechat search [Architecture Technology column] pay attention to this place like sharing. This article architecture technology column has been included, there are a variety of JVM, multi-threading, source code video, information and technical articles waiting for you to take.