中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

南昌簡單做網(wǎng)站/我想找一個營銷團隊

南昌簡單做網(wǎng)站,我想找一個營銷團隊,平面設計師資格證怎么考,精美網(wǎng)站界面依賴包 新建一個工程,包含兩個 module: springboot 模塊,表示 springboot 源碼實現(xiàn);user 模塊,表示業(yè)務系統(tǒng),使用 springboot 模塊; 依賴包:Spring、SpringMVC、Tomcat 等&#xff…

依賴包

新建一個工程,包含兩個 module:

springboot 模塊,表示 springboot 源碼實現(xiàn);
user 模塊,表示業(yè)務系統(tǒng),使用 springboot 模塊;

依賴包:Spring、SpringMVC、Tomcat 等,引入依賴如下:

<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.18</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.3.18</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.18</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version></dependency><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId><version>9.0.60</version></dependency>
</dependencies>

在 user 模塊下引入依賴:

<dependencies><dependency><groupId>org.example</groupId><artifactId>springboot</artifactId><version>1.0-SNAPSHOT</version></dependency>
</dependencies>

定義對應的 controller 和 service:

@RestController
public class UserController {@Autowiredprivate UserService userService;@GetMapping("test")public String test(){return userService.test();}
}

最終希望通過啟動 MyApplication 的 main 方法,啟動項目,能訪問到 UserController。

核心注解和核心類

SpringBoot 的核心類和注解:

@SpringBootApplication,這個注解是加在應用啟動類上的,也就是 main 方法所在的類;
SpringApplication,這個類中有個 run() 方法,用來啟動 SpringBoot 應用的;

所以,自定義類和注解以實現(xiàn)上面的功能。
@FireSpringBootApplication 注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
@ComponentScan
public @interface FireSpringBootApplication {
}

FireSpringApplication 啟動類:

public class FireSpringApplication {public static void run(Class clazz){}
}

在 MyApplication 中使用:

@FireSpringBootApplication
public class MyApplication {public static void main(String[] args) {FireSpringApplication.run(MyApplication.class);}
}

run 方法

需要在 run 方法中啟動 tomcat,通過 tomcat 接收請求;
DispatchServlet 綁定 spring 容器,DispatchServlet 接收到請求后需要在 spring 容器中找到一個 controller 中對應的方法;

run 方法中需要實現(xiàn)的邏輯:

  1. 創(chuàng)建一個 Spring 容器
  2. 創(chuàng)建 Tomcat 對象
  3. 生成 DispatcherServlet 對象,并且和前面創(chuàng)建出來的 Spring 容器進行綁定
  4. 將 DispatcherServlet 添加到 Tomcat 中
  5. 啟動 Tomcat

創(chuàng)建 Spring 容器

public class FireSpringApplication {public static void run(Class clazz){AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();applicationContext.register(clazz);applicationContext.refresh();}
}

run 方法中傳入的即使 MyApplication 類,被解析為 Spring 容器的配置類;
默認會將 MyApplication 所在的包作為掃描路徑,從而掃描到 UserController 和 UserService,所以在 spring 容器啟動后就會存在兩個 bean 了;

啟動 Tomcat

使用內(nèi)嵌的 Tomact,即 Embed-Tomcat,啟動代碼如下:

public static void startTomcat(WebApplicationContext applicationContext){Tomcat tomcat = new Tomcat();Server server = tomcat.getServer();Service service = server.findService("Tomcat");Connector connector = new Connector();// 綁定端口connector.setPort(8081);Engine engine = new StandardEngine();engine.setDefaultHost("localhost");Host host = new StandardHost();host.setName("localhost");String contextPath = "";Context context = new StandardContext();context.setPath(contextPath);context.addLifecycleListener(new Tomcat.FixContextListener());host.addChild(context);engine.addChild(host);service.setContainer(engine);service.addConnector(connector);// 添加DispatcherServlet,并且綁定一個Spring容器tomcat.addServlet(contextPath, "dispatcher", new DispatcherServlet(applicationContext));// 設置Mapping關系context.addServletMappingDecoded("/*", "dispatcher");try {tomcat.start();} catch (LifecycleException e) {e.printStackTrace();}}

在 run 方法中調(diào)用 startTomcat 方法啟動 tomcat:

public static void run(Class clazz){AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();applicationContext.register(clazz);applicationContext.refresh();// 啟動tomcatstartTomcat(applicationContext);}

到此,一個簡單的 SpringBoot 就寫出來了,運行 MyApplication 正常啟動項目,通過瀏覽器就可以訪問 UserController 了。

實現(xiàn) Tomcat 和 Jetty 的切換

前面代碼中默認啟動的是 Tomcat,現(xiàn)在想改成這樣子:

  1. 如果項目中有 Tomcat 的依賴,那就啟動 Tomcat
  2. 如果項目中有 Jetty的依賴就啟動 Jetty
  3. 如果兩者都沒有則報錯
  4. 如果兩者都有也報錯

這個邏輯希望 SpringBoot 自動實現(xiàn),對于程序員用戶而言,只要在 Pom 文件中添加相關依賴就可以了,想用 Tomcat 就加 Tomcat 依賴,想用 Jetty 就加 Jetty 依賴。
Tomcat 和 Jetty 都是應用服務器,或者是 Servlet 容器,可以定義接口來表示它們,這個接口交 WebServer(SpringBoot 源碼中也叫這個)。
定義接口如下:

public interface WebServer {public void start();}

Tomcat 實現(xiàn)類:

public class TomcatWebServer implements WebServer{@Overridepublic void start() {System.out.println("啟動Tomcat");}
}

Jetty 實現(xiàn)類:

public class JettyWebServer implements WebServer{@Overridepublic void start() {System.out.println("啟動Jetty");}
}

在 FireSpringApplication 中的 run 方法中,去獲取對應的 WebServer,然后啟動對應的 webServer。
代碼如下:

public static void run(Class clazz){AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();applicationContext.register(clazz);applicationContext.refresh();// 自動獲取配置的Tomcat或者Jetty容器WebServer webServer = getWebServer(applicationContext);webServer.start();}public static WebServer getWebServer(ApplicationContext applicationContext){return null;
}

模擬實現(xiàn)條件注解

首先實現(xiàn)一個條件注解@FireConditionalOnClass,對應代碼如下:

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Conditional(FireOnClassCondition.class)
public @interface FireConditionalOnClass {String value() default "";
}

注意核心為@Conditional(FireOnClassCondition.class)中的 FireOnClassCondition,因為它才是真正得條件邏輯:

public class FireOnClassCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(FireConditionalOnClass.class.getName());String className = (String) annotationAttributes.get("value");try {context.getClassLoader().loadClass(className);return true;} catch (ClassNotFoundException e) {return false;}}
}

具體邏輯為,拿到@FireConditionalOnClass中的 value 屬性,然后用類加載器進行加載,如果加載到了所指定的這個類,那就表示符合條件,如果加載不到,則表示不符合條件。

模擬實現(xiàn)自動配置類

配置類代碼如下:

@Configuration
public class WebServiceAutoConfiguration {@Bean@FireConditionalOnClass("org.apache.catalina.startup.Tomcat")public TomcatWebServer tomcatWebServer(){return new TomcatWebServer();}@Bean@FireConditionalOnClass("org.eclipse.jetty.server.Server")public JettyWebServer jettyWebServer(){return new JettyWebServer();}
}

表示org.apache.catalina.startup.Tomcat存在,則有 tomcatWebServer 這個bean;
表示org.eclipse.jetty.server.Server存在,則有 jettyWebServer 這個bean;

FireSpringApplication#getWebServer()方法實現(xiàn):

public static WebServer getWebServer(ApplicationContext applicationContext){// key為beanName, value為Bean對象Map<String, WebServer> webServers = applicationContext.getBeansOfType(WebServer.class);if (webServers.isEmpty()) {throw new NullPointerException();}if (webServers.size() > 1) {throw new IllegalStateException();}// 返回唯一的一個return webServers.values().stream().findFirst().get();
}

這樣整體 SpringBoot 啟動邏輯就是這樣的:

  1. 創(chuàng)建一個 AnnotationConfigWebApplicationContext 容器
  2. 解析 MyApplication 類,然后進行掃描
  3. 通過 getWebServer 方法從 Spring 容器中獲取 WebServer 類型的 Bean
  4. 調(diào)用 WebServer 對象的 start 方法

發(fā)現(xiàn)自動配置類

WebServiceAutoConfiguration 需要被 SpringBoot 發(fā)現(xiàn),可以通過 SPI 機制實現(xiàn),比較 JDK 自帶的 SPI 來實現(xiàn)。

在 springboot 項目中的 resources 目錄下添加目錄META-INF/services和文件 org.example.springboot.AutoConfiguration,文件內(nèi)容為org.example.springboot.WebServiceAutoConfiguration。

接口:

public interface AutoConfiguration {
}

WebServiceAutoConfiguration 實現(xiàn)該接口:

@Configuration
public class WebServiceAutoConfiguration implements AutoConfiguration {@Bean@FireConditionalOnClass("org.apache.catalina.startup.Tomcat")public TomcatWebServer tomcatWebServer(){return new TomcatWebServer();}@Bean@FireConditionalOnClass("org.eclipse.jetty.server.Server")public JettyWebServer jettyWebServer(){return new JettyWebServer();}
}

再利用 spring 中的@Import技術來導入這些配置類,我們在@FireSpringBootApplication的定義上增加如下代碼:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
@ComponentScan
@Import(FireImportSelect.class)
public @interface FireSpringBootApplication {
}

FireImportSelect:

public class FireImportSelect implements DeferredImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {ServiceLoader<AutoConfiguration> serviceLoader = ServiceLoader.load(AutoConfiguration.class);List<String> list = new ArrayList<>();for (AutoConfiguration autoConfiguration : serviceLoader) {list.add(autoConfiguration.getClass().getName());}return list.toArray(new String[0]);}
}

如此,Spring 容器可以裝載 WebServiceAutoConfiguration 配置類了,對于 user 模塊而言,不需要修改代碼就可以自動識別 Tomcat 和 Jetty 了。

總結(jié)

到此,實現(xiàn)了一個簡單版本的 SpringBoot,因為 SpringBoot 首先是基于 Spring 的,而且提供的功能也更加強大,后面會對這些功能進行更深入的剖析。

http://www.risenshineclean.com/news/277.html

相關文章:

  • 網(wǎng)站程序前臺/西安百度競價托管公司
  • 做網(wǎng)站待遇/什么是企業(yè)營銷型網(wǎng)站
  • 做網(wǎng)站每頁面費用/bing搜索引擎國際版
  • 企業(yè)網(wǎng)站建設話術/營銷網(wǎng)站
  • wordpress pdf生成/手機端網(wǎng)站優(yōu)化
  • 工信部外國網(wǎng)站備案/b站在線觀看人數(shù)在哪
  • wordpress 時尚主題/駐馬店百度seo
  • 嘉興網(wǎng)站排名優(yōu)化價格/北京網(wǎng)站
  • 網(wǎng)站建設部門/網(wǎng)站軟件下載
  • 建立收費網(wǎng)站/網(wǎng)絡銷售面試問題有哪些
  • 做搞基視頻網(wǎng)站/網(wǎng)絡營銷的案例有哪些
  • 網(wǎng)站怎么做下載連接/百度長尾關鍵詞挖掘
  • 網(wǎng)站彈窗客服代碼/刷推廣鏈接
  • 政府網(wǎng)站公眾號建設方案/谷歌瀏覽器 安卓下載2023版
  • wordpress tutorial/seo優(yōu)化排名服務
  • 網(wǎng)站被谷歌降權/廣州seo招聘網(wǎng)
  • 網(wǎng)站聊天怎么做/最新軍事報道
  • 成都微信端網(wǎng)站建/蘇州seo按天扣費
  • 網(wǎng)站沒有百度快照/全網(wǎng)絡品牌推廣
  • 制作企業(yè)網(wǎng)站需要注意的事項/地推是什么
  • 資料填寫網(wǎng)站類型怎么做/新聞發(fā)稿公司
  • 免費建網(wǎng)站撫順/win10優(yōu)化大師有用嗎
  • 萬盛網(wǎng)站建設公司/當下最流行的營銷方式
  • 下載好看影視大全極速版/seo是什么工作內(nèi)容
  • 重慶響應式網(wǎng)站建設公司/哪個軟件可以自動排名
  • python源碼分享網(wǎng)站/深度搜索
  • 龍華網(wǎng)站建設方案表/免費海報模板網(wǎng)站
  • 關鍵詞seo優(yōu)化/優(yōu)化大師官方免費下載
  • 百度指數(shù) 網(wǎng)站/杭州優(yōu)化公司哪家好
  • 哈爾濱市建設網(wǎng)站/寧波網(wǎng)絡推廣產(chǎn)品服務