zoukankan      html  css  js  c++  java
  • springboot-自动装配

    本次springboot版本:2.1.3.RELEASE

    对于官方组件,是基于condition条件来决定对于类是否要自动装配,

    对于第三方组件,是采用spi机制 来实现扩展

    官方包命名一般是:spring-boot-starter-xxx,如spring-boot-starter-data-redis

    第三方包命令一般是: xxx-spring-boot-starter,如mybatis-plus-boot-starter,pagehelper-spring-boot-starter

    springboot的自动配置使得我们的开发更加的简单,我们在springboot中使用redis时,

    只需要引入redis依赖,配置redis的地址等信息,然后在业务中@Autowired

    @Autowired
    private RedisTemplate redisTemplate;

    就可以使用redisTemplate去操作reids,那么说明redisTemplate已经在ioc容器中,但我们并没有手动去创建一个配置类

    @Configuration
    public class RedisConfiguration {
    
        @Bean
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }

    在spring中,我们可以在配置类中,使用@Bean,@Import,@ComponentScan等注解方式将组件注入到ioc中

    https://www.cnblogs.com/tdyang/p/11867704.html

    但在springboot中我们都没有这样做,那么它是如何注入到容器中的?

    在springboot启动入口的类中,有一个@SpringBootApplication注解

    @SpringBootApplication
    public class MyspringbootApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MyspringbootApplication.class, args);
        }
    
    }

    点进SpringBootApplication我们可以看到:@EnableAutoConfiguration注解,启动自动装配

    @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 {

    点进EnableAutoConfiguration中:我们知道@Import可以将组件导入到容器中

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {

    点进AutoConfigurationImportSelector中:实现了一些接口,

    在spring中,我们可以通过实现ImportSelector接口,返回我们需要导入到ioc容器中的全类名称组件数组,然后通过@Import注解

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

    DeferredImportSelector继承了ImportSelector

    public interface DeferredImportSelector extends ImportSelector {

    在AutoConfigurationImportSelector中的getConfigurations()可以获取到很多的自动配置类,这些配置类就是给容器中导入所需要的所有组件。

        public List<String> getConfigurations() {
                return this.configurations;
            }

     

    点进去其中的一个自动配置类RedisAutoConfiguration ,我们就可以看到RedisTemplate了

    @ConditionalOnClass(RedisOperations.class),就是根据条件进行加载,当我们依赖了spring-boot-starter-data-redis

    这个bean才会去创建

    @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;
        }
    
    }

    那么springboot是怎么知道要扫描哪些路径下的包呢?这里springboot给了一个约定:

    springboot会去扫描classpath:META-INF/spring.factories路径下的包

    对于官方的包:

     我们没有发现有相关的文件,它放在了spring-boot-autoconfigure包下

     

     它会去扫描这些路径进行自动装配。

    # 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

    对于springboot的第三方包:如mybatis,它会去扫描配置文件中的路径org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

    导入需要的组件。

     在springboot中除了使用@ConditionalOnClass等注解来实现按照条件来加载bean,还可以通过spring-autoconfigure-metadata.properties文件

    org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration.AutoConfigureAfter注入的bean,
    org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration注入的条件
    org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration.AutoConfigureAfter=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
    org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration.Configuration=
    org.springframework.boot.autoconfigure.data.neo4j.Neo4jBookmarkManagementConfiguration.Configuration=
    org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration=
    org.springframework.boot.autoconfigure.kafka.KafkaAnnotationDrivenConfiguration.Configuration=
    org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration.ConditionalOnClass=org.influxdb.InfluxDB
    ..........

    既然知道了springboot的自动装配机制,那就可以自己写一个starter

    1、首先创建一个maven项目:

     2、把java和resource目录标记为Resource Root

    3、在Resource 目录下创建META-INF/spring.factories


     4、pom.xml引入spring-boot-starter

     <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter</artifactId>
          <version>2.1.3.RELEASE</version>
          <optional>true</optional>
        </dependency>

    5、写一个自定义的配置类:

    MyRedisStarter 
    public class MyRedisStarter {
    
        public void  print(){
            System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<MyRedisStarter连接redis>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        }
    }

    6、spring.factories文件中:

    key是org.springframework.boot.autoconfigure.EnableAutoConfiguration

    value是配置类的全路径名

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
      com.atyoung.starter.atyoungspringbootstarter.MyRedisStarterConfiguration

    7、maven先clean,然后install

     8、在另外一个springboot项目中引用

     9、启动类中,获取到MyRedisStarter ,并调用print()方法

     这样一个基础的starter就完成了。

    一开始讲到自动装配是采用spi机制来实现扩展

    spi:Service  provider interface

    是java为第三方提供的一种扩展机制,例如java的java.sql.Driver接口有很多驱动实现

    如mysql,orcale等第三方厂商提供的实现,其机制是和上面的差不多。

    简单的写一个实现java.sql.Driver的数据库驱动的demo

    1、首先创建一个maven项目,将java和resource目录的设置和上面一样,为root

     2、创建一个类,实现java.sql.Driver

     3、在resources目录下:创建META-INF和services目录,创建文件java.sql.Driver,是接口全类名

     

     4、文件里面是该接口的实现的全类名

     5、maven进行clean和install

    6、在别的项目里引用

     7、在main方法中去获取到实现了java.sql.Driver的驱动实现

        ServiceLoader<Driver> loaders = ServiceLoader.load(Driver.class);
            for (Driver driver : loaders){
                System.out.println(driver);
            }

    8、打印结果,可以看到自己写的驱动实现

    这样一个简单的sqi扩展点就实现了。

    利用spi我们可以打破双亲委派机制,来达到自己的实现。













  • 相关阅读:
    初识CC_MVPMatrix
    opengl启动过程
    http协议
    sockt套接字编程
    lua元表
    Codeforces 1203F1 Complete the Projects (easy version)
    CodeForces 1200E Compress Words
    CodeForces 1200D White Lines
    HDU 6656 Kejin Player
    HDU 6651 Final Exam
  • 原文地址:https://www.cnblogs.com/tdyang/p/13998367.html
Copyright © 2011-2022 走看看