springboot自动配置

运作原理

关于Spring Boot 的运作原理,我们还是回归到@SpringBootApplication 注解上来,这个注解是一个组合注解,它的核心功能是由@EnableAutoConfiguration 注解提供的。

下面我们来看下@EnableAutoConfiguration 注解的源码:

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

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

    String[] excludeName() default {};
}

这里的关键功能是@Import 注解导入的配置功能,EnableAutoConfigurationImportSelector 使用SpringFactoriesLoader.loadFactoryNames 方法来扫描具有META-INF/spring.factories 文件的jar包,而我们的spring-boot-autoconfigure-1.3.0.x.jar 里就有一个spring.factories 文件,此文件中声明了有哪些自动配置,如图3 所示。

# 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.CloudAutoConfiguration,\
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.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
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.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
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.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\

图3 自动配置

打开上面任意一个AutoConfiguration 文件, 一般都有下面的条件注解, 在 
spring-boot-autoconfigure-1.3.0.x.jar 的org.springframwork.boot.autoconfigure.condition 包下,条件注解如下。

@ConditionalOnBean:当容器里有指定的Bean 的条件下。 
@ConditionalOnClass:当类路径下有指定的类的条件下。 
@ConditionalOnExpression:基于SpEL 表达式作为判断条件。 
@ConditionalOnJava:基于JVM 版本作为判断条件。 
@ConditionalOnJndi:在JNDI 存在的条件下查找指定的位置。 
@ConditionalOnMissingBean:当容器里没有指定Bean 的情况下。 
@ConditionalOnMissingClass:当类路径下没有指定的类的条件下。 
@ConditionalOnNotWebApplication:当前项目不是Web 项目的条件下。 
@ConditionalOnProperty:指定的属性是否有指定的值。 
@ConditionalOnResource:类路径是否有指定的值。 
@ConditionalOnSingleCandidate:当指定Bean 在容器中只有一个,或者虽然有多个但是指定首选的Bean。 
@ConditionalOnWebApplication:当前项目是Web 项目的条件下。

这些注解都是组合了@Conditional 元注解,只是使用了不同的条件(Condition)。

实例分析

在了解了Spring Boot 的运作原理和主要的条件注解后,现在来分析一个简单的Spring Boot 内置的自动配置功能:http 的编码配置。

我们在常规项目中配置http 编码的时候是在web.xml 里配置一个filter,如:

<filter>
  <filter-name>encodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter
  </filter-class>
  <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
  <init-param>
    <param-name>forceEncoding</param-name>
    <param-value>true</param-value>
  </init-param>
</filter>

自动配置要满足两个条件:

  1. 能配置CharacterEncodingFilter 这个Bean;
  2. 能配置encoding 和forceEncoding 这两个参数。

1.配置参数

Spring Boot 的自动配置是基于类型安全的配置实现的,这里的配置类可以在application.properties 中直接设置,源码如下:

@ConfigurationProperties(prefix = "spring.http.encoding")//1
public class HttpEncodingProperties {

    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");//2

    private Charset charset = DEFAULT_CHARSET; //2

    private boolean force = true; //3

    public Charset getCharset() {
       return this.charset;
    }
    public void setCharset(Charset charset) {
       this.charset = charset;
    }

    public boolean isForce() {
       return this.force;
    }

    public void setForce(boolean force) {
       this.force = force;
    }
}

代码解释

① 在application.properties 配置的时候前缀是spring.http.encoding; 
② 默认编码方式为UTF-8,若修改可使用spring.http.encoding.charset=编码; 
③ 设置forceEncoding,默认为true,若修改可使用spring.http.encoding.force=false。

2.配置Bean

通过调用上述配置,并根据条件配置CharacterEncodingFilter 的Bean,我们来看看源码:

@Configuration
@EnableConfigurationProperties(HttpEncodingProperties.class) //1
@ConditionalOnClass(CharacterEncodingFilter.class) //2
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled",
matchIfMissing = true) //3
public class HttpEncodingAutoConfiguration {

   @Autowired
   private HttpEncodingProperties httpEncodingProperties; //3

   @Bean//4
   @ConditionalOnMissingBean(CharacterEncodingFilter.class) //5
   public CharacterEncodingFilter characterEncodingFilter() {
       CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
       filter.setEncoding(this.httpEncodingProperties.getCharset().name());
       filter.setForceEncoding(this.httpEncodingProperties.isForce());
       return filter;
   }
}

代码解释 
① 开启属性注入,通过@EnableConfigurationProperties 声明,使用@Autowired 注入; 
② 当CharacterEncodingFilter 在类路径的条件下; 
③ 当设置spring.http.encoding=enabled 的情况下,如果没有设置则默认为true,即条件符合; 
④ 像使用Java 配置的方式配置CharacterEncodingFilter 这个Bean; 
⑤ 当容器中没有这个Bean 的时候新建Bean。

转载:http://geek.csdn.net/news/detail/115064

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值