<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          從-1開始實(shí)現(xiàn)一個(gè)中間件

          共 9948字,需瀏覽 20分鐘

           ·

          2022-06-26 10:23

          別人都寫從0開始實(shí)現(xiàn)xxx,我先從-1開始就顯得更牛逼一些。

          今天,先開個(gè)頭,來教大家怎么實(shí)現(xiàn)一個(gè)中間件。

          新建項(xiàng)目

          首先,我們新建一個(gè)多 module 的項(xiàng)目用于測試。

          項(xiàng)目包含兩個(gè)模塊,test-infra用戶中間件模塊的開發(fā),demo用于測試。

          <?xml version="1.0" encoding="UTF-8"?>
          <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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

              <modelVersion>4.0.0</modelVersion>
              <parent>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-parent</artifactId>
                  <version>2.7.0</version>
                  <relativePath/> <!-- lookup parent from repository -->
              </parent>
              <groupId>com.aixiaoxian.infra</groupId>
              <artifactId>aixiaoxian-infra</artifactId>
              <version>0.0.1-SNAPSHOT</version>

              <name>aixiaoxian-infra</name>
              <description>aixiaoxian-infra</description>
              <packaging>pom</packaging>

              <properties>
                  <java.version>1.8</java.version>
              </properties>

              <modules>
                  <module>demo</module>
                  <module>test-infra</module>
              </modules>

              <dependencies>

              </dependencies>

              <build>
                  <plugins>
                      <!-- Source -->
                      <plugin>
                          <artifactId>maven-source-plugin</artifactId>
                          <inherited>true</inherited>
                          <executions>
                              <execution>
                                  <phase>package</phase>
                                  <goals>
                                      <goal>jar-no-fork</goal>
                                  </goals>
                              </execution>
                          </executions>
                      </plugin>
                  </plugins>
              </build>

          </project>

          開發(fā)中間件

          項(xiàng)目創(chuàng)建 OK 了,接著開始開發(fā)一個(gè)最最最簡單的中間件。

          resources目錄下創(chuàng)建META-INFA/spring.factories文件,用于自動(dòng)裝配,別問我啥是自動(dòng)裝配,然后配置一個(gè)自動(dòng)裝配類。

          org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
          com.aixiaoxian.testInfra.config.TestConfiguration

          實(shí)現(xiàn) TestConfiguration,最簡單的方式,直接使用@Bean注解聲明一個(gè) Bean 交給 Spring 管理。

          @Configuration
          public class TestConfiguration implements BeanDefinitionRegistryPostProcessorEnvironmentAware {
              private Environment environment;

              @Bean
              public TestManager getTestManager() {
                  return new TestManager();
              }
            
             @Override
              public void setEnvironment(Environment environment) {
                  this.environment = environment;
              }

          }

          然后實(shí)現(xiàn)真正的中間件邏輯的處理部分TestManager

          @Slf4j
          public class TestManager {

              public TestManager() {
                  init();
              }

              public void init(){
                  log.info("TestManager start");
              }
          }

          這樣的話,一個(gè)最簡單的中間件就開發(fā)好了,直接把他添加到demo模塊中,啟動(dòng)測試即可。

           <dependency>
             <groupId>com.aixiaoxian.infra</groupId>
             <artifactId>test-infra</artifactId>
             <version>0.0.1-SNAPSHOT</version>
           </dependency>

          換個(gè)姿勢

          我們換個(gè)姿勢去創(chuàng)建 Bean,使用BeanDefinitionRegistryPostProcessor,讓 TestConfiguration 去實(shí)現(xiàn)它,重寫postProcessBeanDefinitionRegistry,注冊一個(gè)新的 Bean aiManager,這樣也是 OK的,寫法很多,不再贅述。

          @Override
          public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
              BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(AiManager.class);
              beanDefinitionBuilder.addConstructorArgValue(this.environment);
              beanDefinitionRegistry.registerBeanDefinition("aiManager", beanDefinitionBuilder.getBeanDefinition());
          }
          @Slf4j
          public class AiManager {
              private Environment environment;

              public AiManager(Environment environment) {
                  this.environment = environment;

                  init();
              }

              public void init(){
                  log.info("AiManager start");
              }
          }

          再換個(gè)姿勢

          對于自動(dòng)裝配創(chuàng)建 Bean 有了基本的了解,那如果我想聲明一個(gè)注解給別人用該怎么做?

          首先創(chuàng)建一個(gè)注解,注意我使用了@Import注解,TestImportSelector 實(shí)現(xiàn)TestImportSelector接口。

          @Target({ElementType.TYPE})
          @Retention(RetentionPolicy.RUNTIME)
          @Import({TestImportSelector.class})
          @Documented
          public @interface TestAnnotation 
          {
          }

          public class TestImportSelector implements DeferredImportSelector {
              @Override
              public String[] selectImports(AnnotationMetadata annotationMetadata) {
                  return new String[]{AnnotationConfiguration.class.getName()};
              }
          }

          AnnotationConfiguration 寫法也很簡單了,這樣也實(shí)現(xiàn)了自動(dòng)裝配,當(dāng)然了你要是用上面的寫法也能達(dá)到一樣的效果,但是建議這樣寫,別問,問就是這樣。

          public class AnnotationConfiguration implements BeanDefinitionRegistryPostProcessor {

              @Override
              public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
                  BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(AnnotationManager.class);
                  beanDefinitionRegistry.registerBeanDefinition("annotationManager", beanDefinitionBuilder.getBeanDefinition());
              }

              @Override
              public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

              }
          }

          @Slf4j
          public class AnnotationManager {

              public AnnotationManager() {
                  init();
              }

              public void init(){
                  log.info("AnnotationManager start");
              }
          }

          最后在demo啟動(dòng)類上打上我們這個(gè)注解。

          @SpringBootApplication
          @TestAnnotation
          public class DemoApplication {

              public static void main(String[] args) {
                  SpringApplication.run(DemoApplication.classargs);
              }
          }

          最后我們可以看到輸出:

          2022-06-21 19:05:07.433  INFO 4598 --- [           main] c.a.testInfra.manager.TestManager        : TestManager start
          2022-06-21 19:05:07.456  INFO 4598 --- [           main] c.a.testInfra.manager.AiManager          : AiManager start
          2022-06-21 19:05:07.456  INFO 4598 --- [           main] c.a.testInfra.manager.AnnotationManager  : AnnotationManager start

          好了,就這樣,我猜,沒人需要這個(gè)源碼吧?為了后面的文章,先寫個(gè)這個(gè)鋪墊一下,結(jié)束。



          瀏覽 49
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  h片无码| 久久久亚洲AV成人电影 | 怡红院在线观看 | 91福利在线免费观看 | 黄色小电影在线免费观看 |