SpringBoot инкапсулирует наш собственный Starter

Spring Boot
SpringBoot инкапсулирует наш собственный Starter

Обычно мы используем SpringBoot для разработки некоторых сторонних пакетов jar и обычно только вводимxxx-starterВ упаковке jar есть все функции.Какой принцип? Чтобы понять принцип, мы могли бы сначала сделать его вручную.Starter, что будет очень полезно для более глубокого использования некоторых третьих фреймворков.

1. Спецификация разработки SpringBoot Starter

Спецификации, упомянутые в документации официального сайта SpringBoot, примерно следующие:

  • 1. Использование имениspring-boot-starter-xxxxxxэто наше конкретное имя пакета, если оно интегрированоSpring Cloudзатем используйтеspring-cloud-starter-xxx
  • 2, обычно нужно подготовить дваjarФайлы, один из которых не содержит никакого кода, отвечает только за импорт связанных jar-файлов, а другой содержит основной код

какnacosСтартер, интегрированный с Spring Cloud, выглядит следующим образом:

БолееStarterспецификация продукции, мы можем просмотретьОфициальная документация сайта

2. Начальная разработка и этапы разработки

Прежде всего, мы должны понимать, что Springboot загружает сторонние ресурсы.StarterЗа подробностями обращайтесь к другой статье редактораSpringBoot запускает анализ исходного кода и обучение соответствующим навыкам

  • 1. Создайте новыйMavenИнженерия, мы назвали этоstudy-spring-boot-starter

  • 2. Введите связанные зависимости
<dependencies>
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-autoconfigure</artifactId>
    </dependency>
</dependencies>
<dependencyManagement>
    <!-- 我们是基于Springboot的应用 -->
    <dependencies>
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-dependencies</artifactId>
    		<version>2.1.0.RELEASE</version>
    		<type>pom</type>
    		<scope>import</scope>
    	</dependency>
    </dependencies>
</dependencyManagement>

Поскольку нам нужно использовать соответствующие аннотации, предоставляемые Springboot, и использовать функцию автоматической настройки, предоставляемую Springboot, мы должны ввестиspring-boot-autoconfigureиspring-boot-dependenciesдве зависимости.

  • 3. Создайте свой собственный класс автоматической настройки

Вообще говоря, мы можем захотеть предварительно внедрить некоторые из наших собственных bean-компонентов при запуске Springboot.На данный момент нам нужно создать свой собственный класс автоматической конфигурации, обычно используяxxxxEnableAutoConfiguration.

Далее создаем новыйStudyStarterAutoConfiguration.java

package com.example.mystarter.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
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;

import com.example.mystarter.other.Student;

/**
 * 存放我们的配置类,用来配置我们自定义的bean的。既然是一个配置类,那么我们就需要有@Configuration进行声明
 * 
 * @Author jiawei huang
 * @Since 2019年8月23日
 * @Version 1.0
 */
@Configuration
// 导入我们自定义的配置类,供当前类使用
@EnableConfigurationProperties(StudentConfigProperties.class)
// 当存在某个类时,此自动配置类才会生效,这里可以使用外部的String类名
@ConditionalOnClass(Student.class)
// 只有web应用程序时此自动配置类才会生效
@ConditionalOnWebApplication
public class StudyStarterAutoConfiguration {
    /**
     * 当存在study.config.enable=true的配置时,这个Student bean才生效
     * 
     * @return
     */
    @Bean
    @ConditionalOnProperty(prefix = "study.config", name = "enable", havingValue = "true")
    public Student defaultStudent(StudentConfigProperties studyConfigProperties) {
    	Student student = new Student();
    	student.setAge(studyConfigProperties.getAge());
    	student.setName(studyConfigProperties.getName());
    	return student;
    }
}

@ConfigurationОбъявите класс как класс конфигурации

@EnableConfigurationPropertiesЭто означает, что класс, указанный в круглых скобках, внедряется в контейнер как объект bean-компонента, потому что в общем случае путь сканирования пакета по умолчанию, такой как springboot,xxxxxxApplication.javaПакет и все его подпакеты, но бины в некоторых сторонних банках явно не сканируются, и эта аннотация пригодится.Конечно, вы можете сказать, я использую@ComponentScanНет, разница между этими двумя аннотациями заключается в следующем:@ComponentScanПредпосылка состоит в том, что компонент, который вы хотите, уже существует в контейнере компонентов, и@EnableConfigurationPropertiesЭто позволяет контейнеру автоматически находить нужный класс и регистрировать его как bean-компонент.

Springboot предоставляет множество@ConditionАннотация в начале используется для указания операции, которая должна быть выполнена, когда определенное условие выполнено или нет.

@ConditionalOnClassСсылается на этот класс автоконфигурации, когда класс существует.StudyStarterAutoConfigurationвступит в силу, мы можем спросить, мы иногда хотим полагаться на существование стороннего компонента,StudyStarterAutoConfigurationКак это сделать, чтобы вступило в силу (например,mybatisизstarterтребуется исходный кодsqlsessionfactorybeanтоже самое) не паникуйте@ConditionalOnClassЭто также позволяет нам указать полный путь к строке, например.@ConditionalOnClass("com.xxx.xxx")

@ConditionalOnWebApplicationУказывает, что класс конфигурации действует только в том случае, если текущее приложение является приложением веб-сервлета. Это также может ответить, почему исходный код SpringbootSpringApplication.javaЕсть прикладные умозаключения.

@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
	this.resourceLoader = resourceLoader;
	Assert.notNull(primarySources, "PrimarySources must not be null");
	this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
	// 这里会去做推断
	this.webApplicationType = WebApplicationType.deduceFromClasspath();
	setInitializers((Collection) getSpringFactoriesInstances(
			ApplicationContextInitializer.class));
	setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
	this.mainApplicationClass = deduceMainApplicationClass();
}
  • 4. Создаем новыйStudentConfigProperties.java, который объявляет, какие элементы конфигурации может настроить пользователь пускового устройства.
package com.example.mystarter.config;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * 配置项
 * 
 * @Author jiawei huang
 * @Since 2019年8月23日
 * @Version 1.0
 */
@ConfigurationProperties(prefix = "study.config")
public class StudentConfigProperties {
	private int age;

	private String name;

	/**
	 * @return the age
	 */
	public int getAge() {
		return age;
	}

	/**
	 * @param age the age to set
	 */
	public void setAge(int age) {
		this.age = age;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "StudentConfigProperties [age=" + age + ", name=" + name + "]";
	}
}
  • 5. ВresourcesСоздайте новый в каталогеMETA-INFкаталог и создатьspring.factoriesдокумент
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
 com.example.mystarter.config.StudyStarterAutoConfiguration

Наш класс записи автоматической конфигурации, Springboot, просканирует этот файл, и механизм сканирования может просмотреть небольшой написанныйЕще одна запись в блоге

3. Используйте наши собственныеStarter

  • 1. Создаем еще один проект springboot и вводим только чтоstarter
<dependency>
    <groupId>com.example</groupId>
    <artifactId>study</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

Мы создаем новый интерфейс для проверки полезности нашего стартера, код выглядит следующим образом:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.mystarter.config.StudentConfigProperties;
import com.example.mystarter.other.Student;

/**
 * 
 * @Author jiawei huang
 * @Since 2019年8月19日
 * @Version 1.0
 */
@RestController
public class MyController {

	@Autowired
	private Student student;

	@Autowired
	private StudentConfigProperties studentConfigProperties;

	@RequestMapping("/getStudent")
	private String getStudent() {
		return "name=[" + student.getName() + "],age=[" + student.getAge() + "],studentConfigProperties=["
				+ studentConfigProperties + "]";
	}

}

Запустите наш демонстрационный проект, а затем получите доступ к нашему интерфейсу.Результаты следующие:

Ну вот и подошло к концу наше стартерное производство.На самом деле оно очень простое.Предлагаю на основе обучения делать посмотреть на исходники других фреймворков для проверки.Лучше всего реализовать следующее.Может и мы также нужно предоставить Старер для использования другими. Если у вас есть какие-либо вопросы, пожалуйста, не стесняйтесь общаться в области комментариев, спасибо за чтение.