Writing in the front
In view of the message that someone wants to learn SpringBoot related knowledge, I am going to write a related blog about SpringBoot series, the goal is to let students read this series of blog posts, can have a glimpse of SpringBoot. This preliminary set down a series of blog posts including SpringBoot introduction, introduction, configuration, log, web development, data access, combined with related docker, caching, message queue, retrieve, tasks, security, distributed and so on a series of blog posts, a lot of work, is a long process, every step I have detailed as far as possible, deserve to go up screenshot shows, I hope it’s really useful for those of you who are watching. I just want to share technical blog posts, but also want to say that if you think it is useful, please click on the following, give a like, also a relief to me, after all, I have to lose a lot of hair, hey hey hey
Serial article transport bar
Detailed SpringBoot tutorial introduction (1) detailed SpringBoot tutorial introduction (2) detailed SpringBoot tutorial configuration file (1) detailed SpringBoot tutorial configuration file (2) detailed SpringBoot tutorial log framework Detailed SpringBoot tutorial Web development (1) detailed SpringBoot tutorial Web development (2) detailed SpringBoot tutorial Web development (3) detailed SpringBoot tutorial data access detailed SpringBoot tutorial boot configuration principle Detailed SpringBoot tutorial for cache development
Startup Configuration Principles
Here, we just explained that we are actually enough to develop some relatively small SpringBoot applications, but we can with the process of use, the underlying principle of SpringBoot analysis, so that we can really use SpringBoot handy, Then we can also develop our own starter scenario, isn’t that exciting? We’ll talk about it later, but I’ll start with a few important event callback mechanisms
As we mentioned before, our configuration core is usually in meta-INF/Spring.Factories for each configuration, whereas our SpringBoot boot is relevant
- ApplicationContextInitializer
- SpringApplicationRunListener
Just put it in an IOC container
- ApplicationRunner
- CommandLineRunner
Start the process
Create the SpringApplication object
initialize(sources);
private void initialize(Object[] sources) {
// Save the master configuration class
if(sources ! =null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
// Check whether the current application is a Web application
this.webEnvironment = deduceWebEnvironment();
/ / from the classpath find meta-inf/spring. All ApplicationContextInitializer factories configuration; And save it
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
// Find all applicationListeners in the ETA-INF/ spring.Factories configuration from the classpath
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// Find the main configuration class with the main method from multiple configuration classes
this.mainApplicationClass = deduceMainApplicationClass();
}
Copy the code
Run the run method
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
configureHeadlessProperty();
/ / get SpringApplicationRunListeners; Factories from meta-INF /spring.factories under the classpath
SpringApplicationRunListeners listeners = getRunListeners(args);
/ / callback all get SpringApplicationRunListener. Starting () method
listeners.starting();
try {
// Encapsulate command line arguments
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
// Prepare the environment
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
/ / create environment after the completion of the callback SpringApplicationRunListener environmentPrepared (); Indicates that the environment is ready
Banner printedBanner = printBanner(environment);
// Create ApplicationContext; Decide whether to create a Web IOC or a plain IOC
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
// Prepare the context; Save the environment to ioc; And applyInitializers ();
/ / applyInitializers () : the callback previously saved all ApplicationContextInitializer the initialize method
/ / callback all SpringApplicationRunListener contextPrepared ();
//
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
/ / prepareContext completion callback after all SpringApplicationRunListener contextLoaded ();
//s refresh the container; The IOC container is initialized (and embedded Tomcat is also created for Web applications); The Spring annotations version
// Where to scan, create, and load all components; (Configuration classes, components, automatic configuration)
refreshContext(context);
// Get all applicationRunners and CommandLineRunner from the IOC container for callbacks
//ApplicationRunner callback, CommandLineRunner callback
afterRefresh(context, applicationArguments);
/ / all SpringApplicationRunListener finished callback methods
listeners.finished(context, null);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
// Return the ioc container after the SpringBoot application is started;
return context;
}
catch (Throwable ex) {
handleRunFailure(context, listeners, analyzers, ex);
throw newIllegalStateException(ex); }}Copy the code
Event monitoring mechanism
Configuration in the meta-inf/spring. Factories
ApplicationContextInitializer
public class HelloApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("ApplicationContextInitializer... initialize..."+applicationContext); }}Copy the code
SpringApplicationRunListener
public class HelloSpringApplicationRunListener implements SpringApplicationRunListener {
// Mandatory constructor
public HelloSpringApplicationRunListener(SpringApplication application, String[] args){}@Override
public void starting(a) {
System.out.println("SpringApplicationRunListener... starting...");
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
Object o = environment.getSystemProperties().get("os.name");
System.out.println("SpringApplicationRunListener... environmentPrepared.."+o);
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
System.out.println("SpringApplicationRunListener... contextPrepared...");
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
System.out.println("SpringApplicationRunListener... contextLoaded...");
}
@Override
public void finished(ConfigurableApplicationContext context, Throwable exception) {
System.out.println("SpringApplicationRunListener... finished..."); }}Copy the code
Configure (meta-INF /spring.factories)
org.springframework.context.ApplicationContextInitializer=\
com.atguigu.springboot.listener.HelloApplicationContextInitializer
org.springframework.boot.SpringApplicationRunListener=\
com.atguigu.springboot.listener.HelloSpringApplicationRunListener
Copy the code
Just put it in an IOC container
ApplicationRunner
@Component
public class HelloApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("ApplicationRunner... run...."); }}Copy the code
CommandLineRunner
@Component
public class HelloCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("CommandLineRunner... run..."+ Arrays.asList(args)); }}Copy the code
Custom starter
Starter starter starter starter starter starter starter starter starter starter starter starter
Then we will go to the screen here, where we can create modules for empty projects. If we want to have our own launcher, we basically need two modules, but which two modules? We’re going to talk about it here.
We need to be clear about two things, as follows
- What are the dependencies that this scenario needs to use?
- How do I write automatic configuration
Let’s get a starter to do the analysis, as follows
@Configuration // Specify that this class is a configuration class
@ConditionalOnXXX // The auto-configuration class takes effect if the specified condition is true
@AutoConfigureAfter // Specify the order of the auto-configuration classes
@Bean // Add components to the container
@ConfigurationPropertie // Bind the related configuration with the related xxxProperties class
@EnableConfigurationProperties // add xxxProperties to the container
// The auto-configuration class must be loadable
// Automatically configure classes that need to be loaded on startup, configured in meta-INF /spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
Copy the code
Now we
So we should conform to the following pattern:
- Initiators are only used for dependency imports;
- Write an auto-configuration module specifically;
- Initiators rely on automatic configuration. Other people just need to introduce a starter
- Like mybatis-spring-boot-starter, we should name the custom starter -spring-boot-starter
Back to the familiar interface, we will create two, one is a SpringBoot project with nothing checked, and one is a Web module checked only. Once we have created this, we will make the following changes in pom.xml
Initiator module
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atguigu.starter</groupId>
<artifactId>atguigu-spring-boot-starter</artifactId>
<version>1.0 the SNAPSHOT</version>
<! -- Initiator -->
<dependencies>
<! -- Introducing automatic configuration module -->
<dependency>
<groupId>com.atguigu.starter</groupId>
<artifactId>atguigu-spring-boot-starter-autoconfigurer</artifactId>
<version>0.0.1 - the SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Copy the code
Automatic configuration module
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atguigu.starter</groupId>
<artifactId>atguigu-spring-boot-starter-autoconfigurer</artifactId>
<version>0.0.1 - the SNAPSHOT</version>
<packaging>jar</packaging>
<name>atguigu-spring-boot-starter-autoconfigurer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10. 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>
<! -- Introducing spring-boot-starter; Basic configuration of all starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
Copy the code
package com.atguigu.starter;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "atguigu.hello")
public class HelloProperties {
private String prefix;
private String suffix;
public String getPrefix(a) {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix(a) {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix; }}Copy the code
package com.atguigu.starter;
public class HelloService {
HelloProperties helloProperties;
public HelloProperties getHelloProperties(a) {
return helloProperties;
}
public void setHelloProperties(HelloProperties helloProperties) {
this.helloProperties = helloProperties;
}
public String sayHellAtguigu(String name){
return helloProperties.getPrefix()+"-"+name + helloProperties.getSuffix(); }}Copy the code
package com.atguigu.starter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnWebApplication // Only the web application takes effect
@EnableConfigurationProperties(HelloProperties.class)
public class HelloServiceAutoConfiguration {
@Autowired
HelloProperties helloProperties;
@Bean
public HelloService helloService(a){
HelloService service = new HelloService();
service.setHelloProperties(helloProperties);
returnservice; }}Copy the code
The next article
SpringBoot official website actually gives us a lot of cases for reference, integrated with a lot of module example code, SpringBoot on GitHub can be downloaded to run and then study, next time to explain caching.