国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

南昌簡單做網(wǎng)站/我想找一個(gè)營銷團(tuán)隊(duì)

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

依賴包

新建一個(gè)工程,包含兩個(gè) module:

springboot 模塊,表示 springboot 源碼實(shí)現(xiàn);
user 模塊,表示業(yè)務(wù)系統(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>

定義對應(yīng)的 controller 和 service:

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

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

核心注解和核心類

SpringBoot 的核心類和注解:

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

所以,自定義類和注解以實(shí)現(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 容器中找到一個(gè) controller 中對應(yīng)的方法;

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

  1. 創(chuàng)建一個(gè) Spring 容器
  2. 創(chuàng)建 Tomcat 對象
  3. 生成 DispatcherServlet 對象,并且和前面創(chuàng)建出來的 Spring 容器進(jìn)行綁定
  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 容器的配置類;
默認(rèn)會將 MyApplication 所在的包作為掃描路徑,從而掃描到 UserController 和 UserService,所以在 spring 容器啟動后就會存在兩個(gè) 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,并且綁定一個(gè)Spring容器tomcat.addServlet(contextPath, "dispatcher", new DispatcherServlet(applicationContext));// 設(shè)置Mapping關(guān)系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);}

到此,一個(gè)簡單的 SpringBoot 就寫出來了,運(yùn)行 MyApplication 正常啟動項(xiàng)目,通過瀏覽器就可以訪問 UserController 了。

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

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

  1. 如果項(xiàng)目中有 Tomcat 的依賴,那就啟動 Tomcat
  2. 如果項(xiàng)目中有 Jetty的依賴就啟動 Jetty
  3. 如果兩者都沒有則報(bào)錯(cuò)
  4. 如果兩者都有也報(bào)錯(cuò)

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

public interface WebServer {public void start();}

Tomcat 實(shí)現(xiàn)類:

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

Jetty 實(shí)現(xiàn)類:

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

在 FireSpringApplication 中的 run 方法中,去獲取對應(yīng)的 WebServer,然后啟動對應(yīng)的 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;
}

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

首先實(shí)現(xiàn)一個(gè)條件注解@FireConditionalOnClass,對應(yīng)代碼如下:

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

注意核心為@Conditional(FireOnClassCondition.class)中的 FireOnClassCondition,因?yàn)樗攀钦嬲脳l件邏輯:

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 屬性,然后用類加載器進(jìn)行加載,如果加載到了所指定的這個(gè)類,那就表示符合條件,如果加載不到,則表示不符合條件。

模擬實(shí)現(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 這個(gè)bean;
表示org.eclipse.jetty.server.Server存在,則有 jettyWebServer 這個(gè)bean;

FireSpringApplication#getWebServer()方法實(shí)現(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();}// 返回唯一的一個(gè)return webServers.values().stream().findFirst().get();
}

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

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

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

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

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

接口:

public interface AutoConfiguration {
}

WebServiceAutoConfiguration 實(shí)現(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技術(shù)來導(dǎo)入這些配置類,我們在@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é)

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

http://m.aloenet.com.cn/news/277.html

相關(guān)文章:

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