Spring Boot自動配置原理、實戰

Spring Boot自動配置原理

Spring Boot的自動配置註解是@EnableAutoConfiguration, 從上面的@Import的類能夠找到下面自動加載自動配置的映射。java

org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(Class<?>, ClassLoader)
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
	String factoryClassName = factoryClass.getName();
	try {
		Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
				lassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
		List<String> result = new ArrayList<String>();
		while (urls.hasMoreElements()) {
			URL url = urls.nextElement();
			Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
			String factoryClassNames = properties.getProperty(factoryClassName);
			result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
		}
		return result;
	}
	catch (IOException ex) {
		throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
				"] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
	}
}

這個方法會加載類路徑及全部jar包下META-INF/spring.factories配置中映射的自動配置的類。web

/**
 * The location to look for factories.
 * <p>Can be present in multiple JAR files.
 */
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

查看Spring Boot自帶的自動配置的包: spring-boot-autoconfigure-1.5.6.RELEASE.jar,打開其中的META-INF/spring.factories文件會找到自動配置的映射。spring

# 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,\
...

再來看看數據源自動配置的實現註解apache

@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration {
...

@Configuration,@ConditionalOnClass就是自動配置的核心,首先它得是一個配置文件,其次根據類路徑下是否有這個類去自動配置。微信

自動配置實戰

因此,瞭解了自動配置的原理,來本身實現一個自動配置的玩意其實很簡單。app

添加配置類:ide

import org.slf4j.Logger;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;

import com.oceanpayment.common.utils.logger.LoggerUtils;

public class EnvConfig implements EnvironmentAware {

	private final Logger logger = LoggerUtils.getLogger(this);

	private Environment env;

	public String getStringValue(String key) {
		return env.getProperty(key);
	}

	public Long getLongValue(String key) {
		String value = getStringValue(key);
		try {
			return Long.parseLong(value);
		} catch (Exception e) {
			logger.error("字符串轉換Long失敗:{} = {}", key, value);
		}
		return 0L;
	}

	public int getIntValue(String key) {
		return getLongValue(key).intValue();
	}

	@Override
	public void setEnvironment(Environment environment) {
		this.env = environment;
	}

}

添加自動配置類:spring-boot

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.PropertyResolver;

@Configuration
@ConditionalOnClass(PropertyResolver.class)
public class EnvAutoConfig {

	@Bean
	public EnvConfig envConfig() {
		return new EnvConfig();
	}

}

建立META-INF/spring.factories文件,添加自動配置映射:ui

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\
com.oceanpayment.common.config.env.EnvAutoConfig

這樣就搞定了。this

查看自動配置報告

怎麼查看本身加的自動配置類有沒有被加載,或者查看全部自動配置激活的和未激活的能夠經過如下幾種試查看。

一、spring-boot:run運行的在對話框Enviroment中加入debug=true變量
二、java -jar xx.jar --debug
三、main方法運行,在VM Argumanets加入-Ddebug
四、直接在application文件中加入debug=true
五、若是集成了spring-boot-starter-actuator監控,經過autoconfig端點也能夠查看。

啓動後會在控制檯看到如下自動配置報告信息:

=========================
AUTO-CONFIGURATION REPORT
=========================


Positive matches:
-----------------

   AopAutoConfiguration matched:
      - @ConditionalOnClass found required classes 'org.springframework.context.annotation.EnableAspectJAutoProxy', 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
      - @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)
	  
   ...

   EnvAutoConfig matched:
      - @ConditionalOnClass found required class 'org.springframework.core.env.PropertyResolver'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)

   ErrorMvcAutoConfiguration matched:
      - @ConditionalOnClass found required classes 'javax.servlet.Servlet', 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
      - @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)

   ErrorMvcAutoConfiguration#basicErrorController matched:
      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.ErrorController; SearchStrategy: current) did not find any beans (OnBeanCondition)

   ...


Negative matches:
-----------------

   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)

   AopAutoConfiguration.JdkDynamicAutoProxyConfiguration:
      Did not match:
         - @ConditionalOnProperty (spring.aop.proxy-target-class=false) found different value in property 'proxy-target-class' (OnPropertyCondition)

   ArtemisAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory' (OnClassCondition)

   BatchAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'org.springframework.batch.core.launch.JobLauncher' (OnClassCondition)
		 
   ...

Positive matches:已經啓用的自動配置
Negative matches:未啓用的自動配置

從報告中看到本身添加的EnvAutoConfig已經自動配置了。

推薦:Spring Boot & Cloud 最強技術教程

掃描關注咱們的微信公衆號,乾貨天天更新。

image

相關文章
相關標籤/搜索