国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

spring boot--自動化注入組件原理、內(nèi)嵌tomcat-1

這篇具有很好參考價值的文章主要介紹了spring boot--自動化注入組件原理、內(nèi)嵌tomcat-1。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

我們知道開發(fā)spring boot項目,在啟動類上添加注解@SpringBootApplication ,然后引入要自動注入的組件依賴,然后現(xiàn)application.properties中加上相應配置就可以自動注入這個組件,那么下面看看自動注入組件是如何實現(xiàn)的

一、@SpringBootApplication 注解

1、查看SpringBootApplication 類如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
}

2、查看@EnableAutoConfiguration類

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

這個類又通過@Import({AutoConfigurationImportSelector.class}) 導入了
3、AutoConfigurationImportSelector這個bean,查看這個bean

public class AutoConfigurationImportSelector
		implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware,
		BeanFactoryAware, EnvironmentAware, Ordered {
		}

4、這個AutoConfigurationImportSelector類繼承了DeferredImportSelector最終繼承了ImportSelector,重寫這個類的selectImports方法可以快速導入一個bean,查看selectImports方法

@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
				.loadMetadata(this.beanClassLoader);
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List<String> configurations = getCandidateConfigurations(annotationMetadata,
				attributes);
		configurations = removeDuplicates(configurations);
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = filter(configurations, autoConfigurationMetadata);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return StringUtils.toStringArray(configurations);
	}

5、查看List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
這個方法

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
			AnnotationAttributes attributes) {
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
				getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
		Assert.notEmpty(configurations,
				"No auto configuration classes found in META-INF/spring.factories. If you "
						+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}

6、這個方法最終會調(diào)用loadSpringFactories方法,這個方法把META-INF/spring.factories定義的類全部讀到出來
spring boot--自動化注入組件原理、內(nèi)嵌tomcat-1,spring boot,自動化,tomcat

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
        if (result != null) {
            return result;
        } else {
            try {
                Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
                LinkedMultiValueMap result = new LinkedMultiValueMap();

                while(urls.hasMoreElements()) {
                    URL url = (URL)urls.nextElement();
                    UrlResource resource = new UrlResource(url);
                    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                    Iterator var6 = properties.entrySet().iterator();

                    while(var6.hasNext()) {
                        Entry<?, ?> entry = (Entry)var6.next();
                        List<String> factoryClassNames = Arrays.asList(StringUtils.commaDelimitedListToStringArray((String)entry.getValue()));
                        result.addAll((String)entry.getKey(), factoryClassNames);
                    }
                }

                cache.put(classLoader, result);
                return result;
            } catch (IOException var9) {
                throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var9);
            }
        }
    }

7、最終spring會根據(jù)這些組件中定義的注入條件將這些組件自動注入,org.springframework.boot.autoconfigure下放了所有自動注入的組件,以aop這個組件為例:
spring boot--自動化注入組件原理、內(nèi)嵌tomcat-1,spring boot,自動化,tomcat

@Configuration
//條件注入,當有 `EnableAspectJAutoProxy.class, Aspect.class, Advice.class,`這些class存在時才注入,也就是說當引入相關依賴包時注入
		AnnotatedElement.class
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class,
		AnnotatedElement.class })
//當配置文件中有spring.aop 配置時才注入
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

	@Configuration
	@EnableAspectJAutoProxy(proxyTargetClass = false)
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
	public static class JdkDynamicAutoProxyConfiguration {

	}

	@Configuration
	@EnableAspectJAutoProxy(proxyTargetClass = true)
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
	public static class CglibAutoProxyConfiguration {

	}

}
二、spring boot內(nèi)嵌tomcat

最簡單的tomcat集成
1、添加pom文件

<dependencies>

        <!--Java語言操作tomcat -->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>8.5.16</version>
        </dependency>

        <!-- tomcat對jsp支持 -->
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jasper</artifactId>
            <version>8.5.16</version>
        </dependency>

    </dependencies>

2、新建一個servlet文件

public class IndexServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().print("this is index... tomcat");
    }

}

3、新建一個啟動類

public class DTomcat {

    private static int PORT = 8080;
    private static String CONTEX_PATH = "/clock";
    private static String SERVLET_NAME = "indexServlet";

    public static void main(String[] args) throws LifecycleException, InterruptedException {

        // 創(chuàng)建tomcat服務器
        Tomcat tomcatServer = new Tomcat();
        // 指定端口號
        tomcatServer.setPort(PORT);
        // 是否設置自動部署
        tomcatServer.getHost().setAutoDeploy(false);
        // 創(chuàng)建上下文
        StandardContext standardContex = new StandardContext();
        standardContex.setPath(CONTEX_PATH);
        // 監(jiān)聽上下文
        standardContex.addLifecycleListener(new Tomcat.FixContextListener());
        // tomcat容器添加standardContex
        tomcatServer.getHost().addChild(standardContex);

        // 創(chuàng)建Servlet
        tomcatServer.addServlet(CONTEX_PATH, SERVLET_NAME, new IndexServlet());
        // servleturl映射
        standardContex.addServletMappingDecoded("/index", SERVLET_NAME);
        tomcatServer.start();
        System.out.println("tomcat服務器啟動成功..");
        // 異步進行接收請求
        tomcatServer.getServer().await();

    }
}

4、運行main,在瀏覽器輸入:
http://localhost:8080/clock/index

spring boot內(nèi)嵌tomcat
1、啟動一個spring boot項目,查看控制臺最下的日志:
可以看出spring boot在啟動的時候,啟動一個tomcat,實際上它啟動的方式也是上面那么啟動方式
spring boot--自動化注入組件原理、內(nèi)嵌tomcat-1,spring boot,自動化,tomcat
2、tomcat加載流程
tomcat也是一個組件,那么它的引入方式也是通過spring.factories文件注入的
spring boot--自動化注入組件原理、內(nèi)嵌tomcat-1,spring boot,自動化,tomcat
3、查看ServletWebServerFactoryAutoConfiguration這個類
ServletWebServerFactoryAutoConfiguration這個類用@import快速導入了EmbeddedTomcat類
spring boot--自動化注入組件原理、內(nèi)嵌tomcat-1,spring boot,自動化,tomcat
4、查看EmbeddedTomcat類
這個類注入了TomcatServletWebServerFactory這個bean

@Configuration
	@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })
	@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
	public static class EmbeddedTomcat {

		@Bean
		public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
			return new TomcatServletWebServerFactory();
		}

	}

4、查看TomcatServletWebServerFactory類
這個類有一個getWebServer方法如下:
這個方法啟動了一個tomcat,那么這個方法是在哪個地方調(diào)用的?可以在這個方法上打上斷點,查看它的調(diào)用鏈

public WebServer getWebServer(ServletContextInitializer... initializers) {
        Tomcat tomcat = new Tomcat();
        File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat");
        tomcat.setBaseDir(baseDir.getAbsolutePath());
        Connector connector = new Connector(this.protocol);
        tomcat.getService().addConnector(connector);
        this.customizeConnector(connector);
        tomcat.setConnector(connector);
        tomcat.getHost().setAutoDeploy(false);
        this.configureEngine(tomcat.getEngine());
        Iterator var5 = this.additionalTomcatConnectors.iterator();

        while(var5.hasNext()) {
            Connector additionalConnector = (Connector)var5.next();
            tomcat.getService().addConnector(additionalConnector);
        }

        this.prepareContext(tomcat.getHost(), initializers);
        return this.getTomcatWebServer(tomcat);
    }

5、在getWebServer()方法,打斷點,然后啟動spring boot的main方法,查看調(diào)用鏈如下:
spring boot--自動化注入組件原理、內(nèi)嵌tomcat-1,spring boot,自動化,tomcat
6、啟動流程分析
查看main里面的run方法,
這個方法主要new 了一個SpringApplication對象,然后執(zhí)行了run方法

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
    return (new SpringApplication(primarySources)).run(args);
 }

SpringApplication結(jié)構(gòu)方法:
加載了相關類,沒有執(zhí)行

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();
	//從類路徑下找到META-INF/spring.factories配置的所有ApplicationContextInitializer
		setInitializers((Collection) getSpringFactoriesInstances(
				ApplicationContextInitializer.class));
	//從類路徑下找到META-INF/spring.factories配置的所有ApplicationListener
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
}

run方法:

public ConfigurableApplicationContext run(String... args) {
	StopWatch stopWatch = new StopWatch();
	stopWatch.start();
	ConfigurableApplicationContext context = null;
	Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
	configureHeadlessProperty();
	//從類路徑下META‐INF/spring.factories,取得SpringApplicationRunListeners;
	SpringApplicationRunListeners listeners = getRunListeners(args);
//回調(diào)所有的獲取SpringApplicationRunListener.starting()方法
	listeners.starting();
	try {
	    //封裝命令行參數(shù)
		ApplicationArguments applicationArguments = new DefaultApplicationArguments(
				args);
	    //準備環(huán)境
		ConfigurableEnvironment environment = prepareEnvironment(listeners,
				applicationArguments);
		configureIgnoreBeanInfo(environment);
           //創(chuàng)回調(diào)SpringApplicationRunListener.environmentPrepared();
//表示環(huán)境準備完成

		//打印Banner 
		Banner printedBanner = printBanner(environment);
           //根據(jù)環(huán)境創(chuàng)建context
		context = createApplicationContext();
	    //錯誤的異常報表
		exceptionReporters = getSpringFactoriesInstances(
				SpringBootExceptionReporter.class,
				new Class[] { ConfigurableApplicationContext.class }, context);
            //準備上下文環(huán)境;
           //將environment保存到ioc中;
           //applyInitializers()調(diào)用所有的ApplicationContextInitializer的initialize方法
//調(diào)用所有的SpringApplicationRunListener的contextPrepared();
		prepareContext(context, environment, listeners, applicationArguments,
				printedBanner);
//SpringApplicationRunListener的contextLoaded
//刷新容器
//掃描,創(chuàng)建,加載所有組件;
		refreshContext(context);
		afterRefresh(context, applicationArguments);
		stopWatch.stop();
		if (this.logStartupInfo) {
			new StartupInfoLogger(this.mainApplicationClass)
					.logStarted(getApplicationLog(), stopWatch);
		}
		//所有的SpringApplicationRunListener回調(diào)started方法
		listeners.started(context);
		//獲取所有的ApplicationRunner和CommandLineRunner進行調(diào)用
		callRunners(context, applicationArguments);
	}
	catch (Throwable ex) {
		handleRunFailure(context, ex, exceptionReporters, listeners);
		throw new IllegalStateException(ex);
	}

	try {
		//所有的SpringApplicationRunListener的running();
		listeners.running(context);
	}
	catch (Throwable ex) {
		handleRunFailure(context, ex, exceptionReporters, null);
		throw new IllegalStateException(ex);
	}
	return context;
}
三、spring boot內(nèi)嵌tomcat,修改web容器

從spring boot啟動日志看,我們知道spring boot內(nèi)嵌的web容器是tomcat,那么如果我們不想用tomcat 也可以換別的web容器
1、修改pom
排除tomcat,引入undertow容器

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>
    </dependencies>

這個再啟動spring boot項目用的就是undertow容器文章來源地址http://www.zghlxwxcb.cn/news/detail-610103.html

到了這里,關于spring boot--自動化注入組件原理、內(nèi)嵌tomcat-1的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Jenkins + Docker 一鍵自動化部署 Spring Boot 項目,步驟齊全,少走坑路!

    Jenkins + Docker 一鍵自動化部署 Spring Boot 項目,步驟齊全,少走坑路!

    本文章實現(xiàn)最簡單全面的Jenkins+docker+springboot 一鍵自動部署項目,步驟齊全,少走坑路。 環(huán)境 :centos7+git(gitee) 簡述實現(xiàn)步驟:在docker安裝jenkins,配置jenkins基本信息,利用Dockerfile和shell腳本實現(xiàn)項目自動拉取打包并運行。 推薦一個開源免費的 Spring Boot 實戰(zhàn)項目: https://git

    2024年02月08日
    瀏覽(58)
  • 自動化機器學習流水線:基于Spring Boot與AI機器學習技術的融合探索

    自動化機器學習流水線:基于Spring Boot與AI機器學習技術的融合探索

    ?? 作者簡介:阿里巴巴嵌入式技術專家,深耕嵌入式+人工智能領域,具備多年的嵌入式硬件產(chǎn)品研發(fā)管理經(jīng)驗。 ?? 博客介紹:分享嵌入式開發(fā)領域的相關知識、經(jīng)驗、思考和感悟,歡迎關注。提供嵌入式方向的學習指導、簡歷面試輔導、技術架構(gòu)設計優(yōu)化、開發(fā)外包等服

    2024年04月27日
    瀏覽(23)
  • Spring Boot Testing: 使用springboot-test提供的測試框架來實現(xiàn)自動化測試

    作者:禪與計算機程序設計藝術 軟件測試是在開發(fā)過程中不可缺少的一環(huán)。單元測試、集成測試、功能測試等都是為了保證系統(tǒng)的質(zhì)量而進行的測試活動。單元測試主要驗證各個模塊(類、方法)在各種情況下是否正常工作;集成測試則是將不同模塊組合起來看是否可以正常

    2024年02月07日
    瀏覽(23)
  • sqlmap 是一個自動化的 sql 注入滲透工具

    一.介紹 sqlmap 是一個自動化的 sql 注入滲透工具,指紋檢測、注入方式、注入成功后的取數(shù)據(jù)等等都是自動化的,sqlmap 還提供了很多腳本.但在實踐測試的時候基本用不上.用于檢測和利用 Web 應用程序中的 SQL 注入漏洞。它自動化了識別和利用 SQL 注入漏洞的過程,并可用于執(zhí)

    2024年01月23日
    瀏覽(19)
  • Spring Boot中的依賴注入和自動注入

    以下內(nèi)容為本人學習 Spring Boot的依賴注入和自動注入 與ChatGpt提問后對其回答 進行部分修改 (有的錯誤實在是離譜 = =)、格式調(diào)整等操作后的答案, 可能對于其中部分細節(jié)(是錯是對,能力有限有的看不出來 = =),并未做深入探究 ,大家感興趣的話可以自行驗證。 依賴注

    2024年02月06日
    瀏覽(16)
  • 【安全測試學習】自動化注入攻擊之 FuzzDB和Burp 組合拳

    【安全測試學習】自動化注入攻擊之 FuzzDB和Burp 組合拳

    一、FuzzDB 開源的應用程序模糊測試數(shù)據(jù)庫,包含了各種攻擊 payload 的測試用例集合。 主要功能: OS 命令注入 目錄遍歷 文件上傳繞過 身份驗證繞過 XSS SQL 注入 HTTP 頭注入 CRLF 注入 NoSQL 注入等 還包含了一些用不同語言寫成的 webshell 與常用的賬號密碼字典。 github地址: GitH

    2023年04月08日
    瀏覽(18)
  • 【網(wǎng)絡安全-sql注入(5)】sqlmap以及幾款自動化sql注入工具的詳細使用過程(提供工具)

    【網(wǎng)絡安全-sql注入(5)】sqlmap以及幾款自動化sql注入工具的詳細使用過程(提供工具)

    分享一個非常詳細的網(wǎng)絡安全筆記,是我學習網(wǎng)安過程中用心寫的,可以點開以下鏈接獲?。?超詳細的網(wǎng)絡安全筆記 (也可以拿自己的環(huán)鏡來玩,我是用pikachu靶場來演示的) 【網(wǎng)路安全 --- pikachu靶場安裝】超詳細的pikachu靶場安裝教程(提供靶場代碼及工具)_網(wǎng)絡安全_Ai

    2024年02月08日
    瀏覽(19)
  • 使用Burp Suite和Python進行自動化漏洞挖掘—SQL測試注入插件

    使用Burp Suite和Python進行自動化漏洞挖掘—SQL測試注入插件

    每次測注入都是用burp的Intruder模塊,很不方便就是批量跑批量測哪些沒有過濾 懶人鵝上線,準備搞一個sql測試的插件 本篇文章代碼量大,基礎可以去看上一篇 測試sql基本注入的載荷,在可能有sql注入的地方發(fā)送測試包,目前只測試url中的,并可以根據(jù)錯誤回顯判斷出數(shù)據(jù)庫

    2024年02月09日
    瀏覽(26)
  • 自動化測試 - Web自動化測試原理

    自動化測試 - Web自動化測試原理

    目前市面上有很多Web UI自動化測試框架,比如WatiN, Selinimu,WebDriver,還有VS2010中的Coded UI等等. 這些框架都可以操作Web中的控件,模擬用戶輸入,點擊等操作,實現(xiàn)Web自動化測試。其實這些工具的原理都一樣,都是通過調(diào)用IE COM接口和HTML DOM 對IE瀏覽器以及WEB測試對象的操作。

    2024年01月16日
    瀏覽(24)
  • python自動化測試-自動化基本技術原理

    python自動化測試-自動化基本技術原理

    在之前的文章里面提到過:做自動化的首要本領就是要會? 透過現(xiàn)象看本質(zhì) ?,落實到實際的IT工作中就是? 透過界面看數(shù)據(jù) 。 掌握上面的這樣的本領可不是容易的事情,必須要有扎實的計算機理論基礎,才能看到深層次的本質(zhì)東西。 數(shù)據(jù)庫應用系統(tǒng) ?可能是最典型的網(wǎng)絡

    2024年02月10日
    瀏覽(16)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包