SpringBoot的入门(五)

简介: SpringBoot的入门(五)

SpringBoot-@EnableAutoConfiguration项目应用

这个注解在我们做项目中,为了让对象得到统一化的管理的时候,用这个注解的特性是非常的ok的。这个注解可以在springBoot项目run之前进行初始化一系列的配置,比如当我们引入starter-web的时候:会把下面的一个autoconfig的自动配置的包引入进来。在spring中用的一些框架在这里统统都有,比如:amqp(rabbitMQ),Gson等等的对象。

只要我们在run的时候只要在类上面标上这个注解的时候,统统的会把这些配置装配到spriing容器中去。

每一个配置通常都会有三个部分组成:属性的配置文件:

还有一个函数式的接口

最后一个是配置项,在配置项里面有一个注解@ConditionalOnClass(Gson.class):按照条件去装配的注解,当这个Gson.class文件在classpath下存在的话才会把这个配置类的对象装载到spring容器中去,在装配的过程中会把一个Gson的对象装配进来。

@ConditionalOnMissingBean:

在装配Gson对象的时候先去判断容器中是否有Gson类型的对象,如果有的话就不装配,如果没有就去装配。

思考一个问题:在装配的过程中,上面的配置是怎么装配进去的呢?它怎么知道装配的就是这个呢?

在META-INF的文件夹下:有一个spring.factories这个文件内有自动装配类的全路径:这就是配置了进去,这也就是我们什么都不用配置就可以用redisTemplate等等。

而在@EnableAutoConfiguratiion这个注解里面:

  1. package org.springframework.boot.autoconfigure;

  2. import java.lang.annotation.Documented;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Inherited;
  5. import java.lang.annotation.Retention;
  6. import java.lang.annotation.RetentionPolicy;
  7. import java.lang.annotation.Target;
  8. import org.springframework.context.annotation.Import;

  9. @Target({ElementType.TYPE})
  10. @Retention(RetentionPolicy.RUNTIME)
  11. @Documented
  12. @Inherited
  13. @AutoConfigurationPackage
  14. @Import({AutoConfigurationImportSelector.class})
  15. public @interface EnableAutoConfiguration {
  16.    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

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

  18.    String[] excludeName() default {};
  19. }

AutoConfigurationImportSelector这个类里面有一个方法的实现:

selectImports这个方法里做的事是把META-INF里面配置的自动装配类的全路径

统统的装配进来从而返回一个数组出来。

上边的源代码解析:

AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader):带有注解的类就把它加载进来。

AnnotationAttributes attributes =this.getAttributes(annotationMetadata):加载进来后得到所有的属性。Listconfigurations = this.getCandidateConfigurations(annotationMetadata, attributes):

然后通过这个方法getCandidateConfigurations去到META-INF下的spring.factories文件下去获取自动装配的类到这个List集合中去。

  1.  protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
  2.        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
  3.        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.");
  4.        return configurations;
  5.    }

然后把这个集合中重复的东西给排除掉。

configurations =this.removeDuplicates(configurations); Setexclusions = this.getExclusions(annotationMetadata, attributes);

最后返回的数组中的实例对象统统的交给Spring容器管理。

基于上面的特征:完成自己的对象装载:通过@Enable的特征加载第三方的配置类到主类的项目中去。

1、首先创建一个bean-core:对象的配置中心

1.1、创建两个实体类:

1.2、创建一个BeanConfig类:代表第三方的bean的配置类

  1. package org.example.config;

  2. import org.example.domain.Order;
  3. import org.example.domain.Product;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;

  6. @Configuration
  7. public class BeanConfig {
  8.    @Bean
  9.    public   Order CreateOrder(){
  10.        return new Order();
  11.    }
  12.    @Bean
  13.    public Product  CreateProduct(){
  14.        return new Product();
  15.    }
  16. }

2、数据源的配置中心:

2.1、创建一个数据源的类:

  1. package org.example;

  2. /**
  3. * 数据源的属性类
  4. */

  5. public class DataSourceProperties {
  6.    private  String  username;
  7.    private  String  password;
  8.    private  String  url;
  9.    private  String  driverClassName;

  10.    public String getUsername() {
  11.        return username;
  12.    }

  13.    public void setUsername(String username) {
  14.        this.username = username;
  15.    }

  16.    public String getPassword() {
  17.        return password;
  18.    }

  19.    public void setPassword(String password) {
  20.        this.password = password;
  21.    }

  22.    public String getUrl() {
  23.        return url;
  24.    }

  25.    public void setUrl(String url) {
  26.        this.url = url;
  27.    }

  28.    public String getDriverClassName() {
  29.        return driverClassName;
  30.    }

  31.    public void setDriverClassName(String driverClassName) {
  32.        this.driverClassName = driverClassName;
  33.    }
  34. }

2.2、数据源的配置类:

  1. package org.example;

  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;

  5. @Configuration
  6. public class DataSourceConfig {
  7.   @Bean
  8.   @ConfigurationProperties(prefix = "jdbc")
  9.    public DataSourceProperties  dataSourceProperties(){
  10.       return new DataSourceProperties();
  11.   }
  12. }

3:如何在springBoot的项目中去使用这两个配置的核心类呢,在run的时候就把这两个模块给引入过来呢?

3.1、先把两个模块的依赖加入到boot-auto的里面:

  1.          <dependency>
  2.            <groupId>org.example</groupId>
  3.            <artifactId>untitled</artifactId>
  4.            <version>1.0-SNAPSHOT</version>
  5.        </dependency>
  6.        <dependency>
  7.            <groupId>org.example</groupId>
  8.            <artifactId>config-core</artifactId>
  9.            <version>1.0-SNAPSHOT</version>
  10.        </dependency>

3.2、根据@EnableAutoConfiguration的特性,可以自己在两个模块中去创建分别去创建META-INF/spring.factories文件:

这两个配置文件spring.factories会合并成一个然后做排除重复的。然后交给Spring容器去管理。

4:运行下主函数:这就把bean-core中的Order对象的实例在boot-auto项目中给拿了出来。

4.1:也可以通过context对象把配置类拿出来:

4.2、在boot-auto的工程里面配置的属性配置文件里面配置数据源的drvicerClassName配置信息如下:

在主类中就可以拿到driverClassName的信息。

上面的就是很灵活的方式。

上面的功能在cloud中的config中已经存在了。


所以说一般好的架构都是在第三方的工程里配置比如:redis,mongdb,mysql。

相关文章
|
13小时前
|
Java Spring 容器
SpringBoot的入门(三)
SpringBoot的入门(三)
|
13小时前
|
Java API 容器
SpringBoot入门(十)
SpringBoot入门(十)
|
13小时前
|
监控 Java Spring
SpringBoot的入门(四)
SpringBoot的入门(四)
|
13小时前
|
JSON Java 数据格式
SpringBoot入门(七)
SpringBoot入门(七)
|
13小时前
|
Java Spring 容器
SpringBoot的入门(二)
SpringBoot的入门(二)
|
13小时前
|
JSON Java API
SpringBoot入门(八)
SpringBoot入门(八)
|
13小时前
|
NoSQL Java Redis
SpringBoot的入门(一)
SpringBoot的入门(一)
|
3月前
|
Java 数据库连接 Maven
|
3月前
|
Java Maven Spring
2.springboot入门
2.springboot入门
23 0
|
3月前
|
Java 应用服务中间件 数据库