zoukankan      html  css  js  c++  java
  • (一)springboot原理——自动装配

    1.spring配置方式

    1.1XML方式

    package com.mine.boot.version1;
    
    public class InstA {
    
        public InstA() {
            System.out.println("InstA实例化");
        }
    
    }
    
    package com.mine.boot.version1;
    
    public class InstB {
        public InstB() {
            System.out.println("InstB实例化");
        }
    }
    

    spring-bean.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
    
    
        <bean id="instA" class="com.mine.boot.version1.InstA"></bean>
    
        <bean id="instB" class="com.mine.boot.version1.InstB"></bean>
    </beans>
    

    获取IOC容器中的Bean

        public static void main(String[] args) {
            ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
            InstA instA = classPathXmlApplicationContext.getBean(InstA.class);
            System.out.println(instA);
        }
    

    运行结果:

    16:35:49.334 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 2 bean definitions from class path resource [spring-bean.xml]
    16:35:49.386 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'instA'
    InstA实例化
    16:35:49.402 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'instB'
    InstB实例化
    com.mine.boot.version1.InstA@33c7e1bb
    

    1.2JavaConfig方式

    package com.mine.boot.version2;
    
    public class InstA {
    
        public InstA() {
            System.out.println("InstA实例化");
        }
    
    }
    
    
    package com.mine.boot.version2;
    
    public class InstB {
        public InstB() {
            System.out.println("InstB实例化");
        }
    }
    
    package com.mine.boot.version2;
    
    

    BeanConfig

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class BeanConfig {
    
        @Bean
        public InstA instA() {
            return new InstA();
        }
    
        @Bean
        public InstB instB() {
            return new InstB();
        }
    }
    

    获取IOC容器中的Bean

        public static void main(String[] args) {
            AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
            InstA instA = annotationConfigApplicationContext.getBean(InstA.class);
            System.out.println(instA);
        }
    

    运行结果:

    16:39:34.677 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'instA'
    InstA实例化
    16:39:34.693 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'instB'
    InstB实例化
    com.mine.boot.version2.InstA@4f638935
    

    2.SpringBoot介绍

    来自:百度百科
    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。

    SpringBoot所具备的特征有:

    • 可以创建独立的Spring应用程序,并且基于其Maven或Gradle插件,可以创建可执行的JARs和WARs;
    • 内嵌Tomcat或Jetty等Servlet容器;
    • 提供自动配置的“starter”项目对象模型(POMS)以简化Maven配置;
    • 尽可能自动配置Spring容器;
    • 提供准备好的特性,如指标、健康检查和外部化配置;
    • 绝对没有代码生成,不需要XML配置。

    自我理解:
    springboot 简化了传统项目中组件依赖的配置方式 如:
    1.若项目中需要mcv组件,需要手动添加mvc相关的各个jar包(maven依赖或手动导入),而springboot只需要添加一个spring-boot-starter-web依赖就可以把spring核心,spring-web,spring-webmvc,tomcat容器相关的包加载进来,减少了资源包的配置过程。
    2.自动配置,通过springboot定义好的配置类,完成各个组件所需要的配置基本过程,减少了整合第三方组件的配置过程,如redisTemplate。

    3.springBoot自动装配

    springboot启动的入口:SpringApplication.run(BootApplication.class, args)方法

    @RestController
    @SpringBootApplication
    public class BootApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(BootApplication.class, args);
        }
    
        @RequestMapping("hi")
        public String hi() {
            return "hi boot";
        }
    
    }
    

    @SpringBootApplication注解:

    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = {
    		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    		@Filter(type = FilterType.CUSTOM,
    				classes = AutoConfigurationExcludeFilter.class) })
    public @interface SpringBootApplication {
    

    @SpringBootApplication注解中比较重要的有三个:

    • @SpringBootConfiguration:==》里面其实是@Configuration,说明BootApplication类也是一个JavaConfig配置类(等同于bean.xml),可以在BootApplication类里面定义@Bean等配置信息。
    • @ComponentScan:包扫描,扫描当前类所在包,以及子包下的注解类(@Controller,@Service,@Repository,@Component)加入到IOC容器中。
    • @EnableAutoConfiguration:重点是@Import(AutoConfigurationImportSelector.class)自动配置导入选择,它帮我们导入AutoConfigurationImportSelector类。

    springboot启动调用SpringApplication.run()方法,在run()方法中有一个refreshContext(context)方法,刷新spring的容器,在这个过程中,spring会解析当前类的@SpringBootApplication的注解,会调用AutoConfigurationImportSelector类中的selectImports(AnnotationMetadata annotationMetadata)方法,该方法下有个getCandidateConfigurations()方法(获取候选配置)

            /*
            所有的配置都存放在configurations中,
            而这些配置都从getCandidateConfiguration中获取,
            这个方法是用来获取候选的配置。
            */
    	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;
    	}
    
    

    loadSpringFactories()方法加载类路径下的(FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories") 的spring.factories文件

    	private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
    		MultiValueMap<String, String> result = cache.get(classLoader);
    		if (result != null) {
    			return result;
    		}
    
    		try {
    			Enumeration<URL> urls = (classLoader != null ?
    					classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
    					ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
    			...
    		}
    	}
    

    spring.factories文件下Auto Configure:也就是会获取可能依赖的组件的配置类的全路径,也不是全部XXXAutoConfiguration都会加载,也会根据@ConditionalOnXXX条件注解选择性加载配置类,加载的配置类中定义的Bean会加入到IOC容器中,从而实现自动装配。

    # 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,
    org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,
    org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,
    org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,
    org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,
    org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,
    org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,
    org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,
    org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,
    org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,
    org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,
    org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,
    org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,
    org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,
    org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,
    org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,
    org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration,
    org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,
    org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,
    org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,
    org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,
    org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,
    org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,
    org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,
    org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,
    org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,
    org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,
    org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,
    org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,
    org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,
    org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,
    org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,
    org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,
    org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,
    org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,
    org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,
    org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,
    org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,
    org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,
    org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,
    org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,
    org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,
    org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,
    org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,
    org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,
    org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,
    org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,
    org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,
    org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,
    org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,
    org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,
    org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,
    org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,
    org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,
    org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,
    org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,
    org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,
    org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,
    org.springframework.boot.autoconfigure.security.servlet.SecurityRequestMatcherProviderAutoConfiguration,
    org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,
    org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,
    org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,
    org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,
    org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,
    org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,
    org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,
    org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,
    org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,
    org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,
    org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,
    org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,
    org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,
    org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,
    org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,
    org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,
    org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,
    org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,
    org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,
    org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,
    org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,
    org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,
    org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,
    org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,
    org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,
    org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,
    org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,
    org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,
    org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,
    org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,
    org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,
    org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,
    org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,
    org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,
    org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,
    org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
    

    案例:redis自动配置
    org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,

    @Configuration
    @ConditionalOnClass(RedisOperations.class)
    @EnableConfigurationProperties(RedisProperties.class)
    @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
    public class RedisAutoConfiguration {
    
    	@Bean
    	@ConditionalOnMissingBean(name = "redisTemplate")
    	public RedisTemplate<Object, Object> redisTemplate(
    			RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    		RedisTemplate<Object, Object> template = new RedisTemplate<>();
    		template.setConnectionFactory(redisConnectionFactory);
    		return template;
    	}
    
    	@Bean
    	@ConditionalOnMissingBean
    	public StringRedisTemplate stringRedisTemplate(
    			RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    		StringRedisTemplate template = new StringRedisTemplate();
    		template.setConnectionFactory(redisConnectionFactory);
    		return template;
    	}
    
    }
    

    RedisProperties:

    @ConfigurationProperties(prefix = "spring.redis")
    public class RedisProperties {
    
    	/**
    	 * Database index used by the connection factory.
    	 */
    	private int database = 0;
    
    	/**
    	 * Connection URL. Overrides host, port, and password. User is ignored. Example:
    	 * redis://user:password@example.com:6379
    	 */
    	private String url;
    
    	/**
    	 * Redis server host.
    	 */
    	private String host = "localhost";
    
    	/**
    	 * Login password of the redis server.
    	 */
    	private String password;
    
    	/**
    	 * Redis server port.
    	 */
    	private int port = 6379;
    
    	/**
    	 * Whether to enable SSL support.
    	 */
    	private boolean ssl;
    
    	/**
    	 * Connection timeout.
    	 */
    	private Duration timeout;
    
    	private Sentinel sentinel;
    
    	private Cluster cluster;
    
    	private final Jedis jedis = new Jedis();
    
    	private final Lettuce lettuce = new Lettuce();
    
            ......
    

    流程:

    结论:
    SpringBoot所有自动配置类都是在启动的时候进行扫描并加载,通过spring.factories可以找到自动配置类的路径,但是不是所有存在于spring,factories中的配置都进行加载,而是通过@ConditionalOnClass注解进行判断条件是否成立(只要导入相应的stater,条件就能成立),如果条件成立则加载配置类,否则不加载该配置类。

    在这里贴一个我认为的比较容易理解的过程:

    • SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值
    • 将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;
    • 以前我们需要自己配置的东西 , 自动配置类都帮我们解决了
    • 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;
    • 它将所有需要导入的组件以全类名的方式返回 , 这些组件就会被添加到容器中 ;
    • 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;
    • 有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;

    参考:https://zhuanlan.zhihu.com/p/95217578

  • 相关阅读:
    VM439:1 https://unidemo.dcloud.net.cn 不在以下 request 合法域名列表中,请参考
    vue点击出现蒙版
    vue实现轮播图
    js函数调用的几种方法
    js中的object类型
    vue报错笔记
    vue中项目如何引入sass (vue-cli项目)
    vue编写轮播图组件
    VSCode配置 Debugger for Chrome插件
    就是一段程序,可以求出N个不等长列表中取N个元素形成的所有组合
  • 原文地址:https://www.cnblogs.com/everyingo/p/14583523.html
Copyright © 2011-2022 走看看