SpringBoot 自动装配原理

根据之前的学习,在搭建springboot项目时,我们可以简化很多配置。那springboot是如何做到的呢?

首先我们来看JAVA WEB的启动过程
点这里

web项目需要部署容器(tomcat\weblogic等),容器会首先加载web项目中的 web.xml文件。

项目的启动顺序首先是context-param,接着是listener,在接下来是filter,最后才是servlet。
知识点 过滤器和拦截器

SpringBoot 自动装配原理_第1张图片

SpringMVC
springmvc的启动过程也是基于上述过程。

tomcat容器 会将读取到转化为键值对,并交给ServletContext(上下文) ,供整个WEB项目使用

 
    contextConfigLocation
    classpath:applicationContext-*.xml
  

在执行玩上下文加载后会建立监听,ServletContextListener作为监听类的根接口contextInitialized,contextDestroyed两个方法。

 
  
    org.springframework.web.context.ContextLoaderListener
  

而 ContextLoaderListener 重写了 contextInitialized 方法

@Override
	public void contextInitialized(ServletContextEvent event) {
		initWebApplicationContext(event.getServletContext());
	}

初始化Web应用上下文,initWebApplicationContext中调用configureAndRefreshWebApplicationContext对IoC容器的配置和刷新操作。

该方法主要用于创建并初始化contextConfigLocation类配置的xml文件中的Bean,因此,如果我们在配置Bean时出错,在Web应用启动时就会抛出异常,而不是等到运行时才抛出异常。

filter初始化
servlet初始化
常用DispatcherServlet类,DispatcherServlet类间接父类实现了Servlet接口,创建一个IOC子容器,并加载标签的配置的xml文件并加载相关Bean。

SpringBoot的启动过程
spring boot

我们来看springboot的启动类

@SpringBootApplication
@Slf4j
public class Application
{


  public static void main(String[] args)
  {
    log.info("=================开始成功=================");
    SpringApplication.run(Application.class, args);
    log.info("=================启动成功=================");
  }

@SpringBootApplication注解是springboot启动的开始,我们来看看

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class))
public @interface SpringBootApplication {
	Class[] exclude() default {};
	String[] excludeName() default {};

	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
	String[] scanBasePackages() default {};

	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
	Class[] scanBasePackageClasses() default {};
}

@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan 是其中最重要的三个注解

@SpringBootConfiguration 注解
@SpringBootConfiguration其实就是@Configuration,熟悉spring的都知道,@Configuration 是一个类级注释,指示对象是一个bean定义的源。@Configuration 类通过 @bean 注解的公共方法声明bean。减少xml配置。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

例如:

 
         
                 
         
         
                 
         
 

使用@Configuration

@Configuration 
public class ApplicationConfig { 
   
        public @Bean OrderService orderService() { 
                return new OrderService(orderRepository()); 
        } 
   
        public @Bean OrderRepository orderRepository() { 
                return new OrderRepository(dataSource()); 
        } 
   
        public @Bean DataSource dataSource() { 
        } 
} 

@ComponentScan告诉Spring 哪个packages 的用注解标识的类 会被spring自动扫描并且装入bean容器。

@EnableAutoConfiguration
点这里

@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

	Class[] exclude() default {};
	String[] excludeName() default {};
}

@EnableAutoConfiguration让Spring Boot根据类路径的jar包依赖为当前项目进行自动化配置。

例如,添加了spring-boot-starter-web依赖,会自动添加Tomcat和Spring MVC的依赖,那么Spring Boot会对Tomcat和Spring MVC进行自动配置。

又如,添加了spring-boot-starter-data-jpa依赖,Spring Boot会自动进行JPA相关的配置。

进入@EnableAutoConfiguration
SpringBoot 自动装配原理_第2张图片

查看getCandidateConfigurations方法

protected List getCandidateConfigurations(AnnotationMetadata metadata,
			AnnotationAttributes attributes) {
		List 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;
	}

SpringFactoriesLoader.loadFactoryNames加载META-INF/spring.factories文件中jar文件

例如spring-boot-1.4.2.RELEASE.jar 中的META-INF/spring.factories

org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener,\
org.springframework.boot.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.logging.LoggingApplicationListener

# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor

# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer

# FailureAnalysisReporters
org.springframework.boot.diagnostics.FailureAnalysisReporter=\
org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter

我们在springmvc中使用redis
spring+redis

需要配置一些bean,如:

   
    
        
        
            
        
        
            
        
        
            
        
        
            
        
           
          
    

才可以使用

@Autowired 
    public RedisTemplate redisTemplate;

在springboot中
可以直接从容器中拿去RedisTemplate bean对象
在spring-boot-autoconfigure依赖包中有一个spring.factories文件
SpringBoot 自动装配原理_第3张图片

查看 这个RedisAutoConfiguration类

		@Bean
		@ConditionalOnMissingBean(StringRedisTemplate.class)
		public StringRedisTemplate stringRedisTemplate(
				RedisConnectionFactory redisConnectionFactory)
						throws UnknownHostException {
			StringRedisTemplate template = new StringRedisTemplate();
			template.setConnectionFactory(redisConnectionFactory);
			return template;
		}

你可能感兴趣的:(Spring,SpringBoot,原理)