SpringBoot自动配置原理

底层注解

@Configuration配置类

  • @Configuration : 告诉SpringBoot这是一个配置类
  • 配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
  • 配置类本身也是组件
  • proxyBeanMethods : 代理bean的方法
    • Full(proxyBeanMethods = true)【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
    • Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
    • 组件依赖必须使用Full模式默认。其他默认是否Lite模式
    • 配置类中的方法之间没有互相调用,用Lite模式,就将proxyBeanMethods = false,这样SpringBoot就不会每次启动都花时间检查容器中组件的依赖关系
    • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式(即如,某个对象可能需要用到另一个对象,这就叫存在依赖关系)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {

	@AliasFor(annotation = Component.class)
	String value() default "";

	/*
	 * 指定是否应代理@Bean方法以强制执行Bean生命周期行为,
	 * 例如,即使在用户代码中直接调用@Bean方法的		
	 * 情况下,也返回共享的单例Bean实例。此功能需要方法拦截,
	 * 通过运行时生成的CGLIB子类实现,该子类有一些限制,例如不允许配置类及其方法声明final。
	 * 
	 * 默认值为true,允许通过配置类内的直接方法调用进行“bean间引用”,
	 * 以及外部调用此配置的@bean方法,例如从另一个配置类进行调用。
	 * 如果由于此特定配置的@Bean方法都是自包含的,并且设计为容器使用的普通工厂方法,
	 * 因此不需要这样做,请将此标志切换为false,以避免CGLIB子类处理。
	 */
	boolean proxyBeanMethods() default true;

}

Configuration使用示例

/**
 * 1.@Configuration : 告诉SpringBoot这是一个配置类
 * 2.配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
 * 3.配置类也是组件
 * 4.proxyBeanMethods : 代理bean的方法
 *      Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
 *      Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
 *      组件依赖必须使用Full模式默认。其他默认是否Lite模式
 */
@Configuration(proxyBeanMethods = true)
public class MyConfig {

    /**
     * @Bean : 给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
     *
     * Full模式:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
     *
     * @return User
     */
    @Bean
    public User getUser() {
        User user = new User();
        user.setAge(18);
        user.setName("zhang");
        // user组件依赖了Pets组件
        user.setPets(getTomcat());
        return user;
    }

    @Bean(name = "tom")
    public Pets getTomcat() {
        Pets pets = new Pets();
        pets.setName("Tomcat");
        return pets;
    }
}

从容器中获取组件

/**
 * 主程序类
 * @SpringBootApplication : 这是一个SpringBoot应用
 */
@SpringBootApplication
public class MainApplication {

    public static void main(String[] args) {

        // 1.返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        // 2.查看容器里的组件
        String[] beanDefinitionNames = run.getBeanDefinitionNames();

        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }

        // 3.从容器了获取组件
        User user1 = run.getBean("getUser", User.class);
        User user2 = run.getBean("getUser", User.class);

        System.out.println("组件:" + (user1 == user2)); // 组件:true 说明是单列的


        // 4.com.kernel.boot.config.MyConfig$$EnhancerBySpringCGLIB$$eedda4d0@2577d6c8
        MyConfig bean = run.getBean(MyConfig.class);
        System.out.println(bean);

        // 如果@Configuration(proxyBeanMethods = true) 代理对象调用方法,
        // SpringBoot总会检查这个组件是否在容器中保持组件单列
        // 总结:使用代理,容器实例唯一,不使用代理,多次调用多个实例
        User user3 = bean.getUser();
        User user4 = bean.getUser();
        System.out.println(user3 == user4); // true

        // 组件依赖
        User user5 = run.getBean("getUser", User.class);
        Pets tom = run.getBean("tom", Pets.class);
        System.out.println("用户的宠物:"+(user5.getPets() == tom)); // 用户的宠物:true

    }
}

容器中注册组件的其它注解
@Bean、@Component、@Controller、@Service、@Repository

@Import

@Configuration类可以使用@Import注解来进行组合,将多个配置类组合在一起。类似于SpringXML中<Import>的工作方式。@Configuration对象在容器中作为Spring bean进行管理,所以可以注入导入的配置,例如,通过构造函数注入:

@Configuration
public class DatabaseConfig {
    @Bean
    public DataSource dataSource() {
        // instantiate, configure and return DataSource
    }
}
  
@Configuration //类似总配置类
// 将DatabaseConfig  加进来
@Import(DatabaseConfig.class)
public class AppConfig {

   private final DatabaseConfig dataConfig;

   public AppConfig(DatabaseConfig dataConfig) {
       this.dataConfig = dataConfig;
   }

   @Bean
   public MyBean myBean() {
       // reference the dataSource() bean method
       return new MyBean(dataConfig.dataSource());
   }
}

@Conditional条件装配

条件装配:满足Conditional指定的条件,则进行组件注入

在这里插入图片描述
条件装配示例@ConditionalOnBean

@Configuration
public class MyConfig {

    @Bean
    @ConditionalOnBean(name = "tom") // 当容器中有tom这个组件才进行注入
    public User getUser() {
        User user = new User();
        user.setAge(18);
        user.setName("zhang");
        user.setPets(getTomcat());
        return user;
    }

    public Pets getTomcat() {
        Pets pets = new Pets();
        pets.setName("Tomcat");
        return pets;
    }
}
/**
 * 主程序类
 * @SpringBootApplication : 这是一个SpringBoot应用
 */
@SpringBootApplication
public class MainApplication {

    public static void main(String[] args) {

        // 1.返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        // 2.查看容器里的组件
        String[] beanDefinitionNames = run.getBeanDefinitionNames();

        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }

        boolean tom = run.containsBean("tom");
        System.out.println("容器中是否有tom组件" + tom); // 容器中是否有tom组件false

        boolean getUser = run.containsBean("getUser");
        System.out.println("容器中是否有getUser组件" + getUser); // 容器中是否有getUser组件false
        
    }
}

@ImportResource

@ImportResource(“classpath:beans.xml”)用来导入指定的配置文件。

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="haha" class="com.kernel.boot.bean.User">
        <property name="name" value="zhangsan"></property>
        <property name="age" value="18"></property>
    </bean>

    <bean id="hehe" class="com.kernel.boot.bean.Pets">
        <property name="name" value="tomcat"></property>
    </bean>
</beans>
@Configuration
@ImportResource("classpath:beans.xml")
public class MyConfig {

    @Bean(name = "tom")
    public Pets getTomcat() {
        Pets pets = new Pets();
        pets.setName("Tomcat");
        return pets;
    }
}

测试

/**
 * 主程序类
 * @SpringBootApplication : 这是一个SpringBoot应用
 */
@SpringBootApplication
public class MainApplication {

    public static void main(String[] args) {

        // 1.返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        // 2.查看容器里的组件
        String[] beanDefinitionNames = run.getBeanDefinitionNames();

        boolean haha = run.containsBean("haha");
        boolean hehe = run.containsBean("hehe");
        System.out.println("haha:" + haha); // true
        System.out.println("hehe:" + hehe); // true
    }
}

@ConfigurationProperties

读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用。

application.properties

car.brand=BYD
car.price=10000

Car

/**
 * @ClassName Car
 * @author: shouanzh
 * @Description 只有在容器中的组件,才会拥有SpringBoot提供的强大功能
 * @date 2022/4/7 23:44
 */

@Component
@ConfigurationProperties(prefix = "car") // prefix 指定前缀
//@PropertySource("classpath:app.properties") 指定配置文件
@Data
public class Car {

    private String brand;

    private Integer price;

}

测试

@RestController
public class HelloController {

    @Autowired
    private Car car;

    @RequestMapping("/hello")
    public String hello() {
        System.out.println(car.getBrand()); // BYD
        System.out.println(car.getPrice()); // 10000
        return "Hello, Spring Boot 2!";
    }
}

方式二

@ConfigurationProperties(prefix = "car") // prefix 指定前缀
@Data
public class Car {

    private String brand;

    private Integer price;

}
@Configuration
@EnableConfigurationProperties(Car.class)
//1、开启Car配置绑定功能
//2、把这个Car这个组件自动注册到容器中
public class MyConfig {
}

自动配置原理

核心注解:@SpringBootApplication
在这里插入图片描述

@SpringBootConfiguration

@Configuration : 代表当前是一个配置类

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

	@AliasFor(annotation = Configuration.class)
	boolean proxyBeanMethods() default true;

}

@ComponentScan

扫描路径,默认值扫描main的同级和下级路径,scan可以添加上级路径。

例如,如果类中用了@Controller,@Repository,@Service,@Component四大注解之一标识了,那么如果不加上@ComponentScan,Spring就不会自动扫描类上的四大注解中的任何一个,那么四大注解下的类就不会被Spring扫描到,更不会装入Spring容器中,因此你配置的四大注解就失去了作用。

@EnableAutoConfiguration

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

	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

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

	String[] excludeName() default {};

}

可以看到@EnableAutoConfiguration由@AutoConfigurationPackage和@Import(AutoConfigurationImportSelector.class)合成。

@AutoConfigurationPackage

自动配置包:指定了默认的包规则

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class) // 导入组件
public @interface AutoConfigurationPackage {

	String[] basePackages() default {};

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

}

我们看一下Registrar

在这里插入图片描述
利用Registrar给容器中导入一系列组件
将指定的一个包下的所有组件导入进来。MainApplication 所在包下。

@Import(AutoConfigurationImportSelector.class)

跟一下AutoConfigurationImportSelector源码
在这里插入图片描述
1、利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
在这里插入图片描述
在这里插入图片描述

2、调用List configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类

在这里插入图片描述

3、利用工厂加载 Map<String, List> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件

在这里插入图片描述

4、从META-INF/spring.factories位置来加载一个文件。
默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories
在这里插入图片描述
文件里面写死了spring-boot一启动就要给容器中加载的所有配置类
spring-boot-autoconfigure-2.3.4.RELEASE.jar/META-INF/spring.factories

# 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.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
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.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
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.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
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.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
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.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
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.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
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.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
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

按需开启自动配置项

虽然我们130个场景的所有自动配置启动的时候默认全部加载:xxxxAutoConfiguration。

按照条件装配规则(@Conditional),最终会按需配置。

我们来分析一下AOP自动配置是否生效
在这里插入图片描述

package org.springframework.boot.autoconfigure.aop;

import org.aspectj.weaver.Advice;

import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

// 配置类
@Configuration(proxyBeanMethods = false) 
// 配置文件是否存在 spring.aop.auto=true  matchIfMissing = true:就算没配也按照true
// 说明AopAutoConfiguration生效
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

	@Configuration(proxyBeanMethods = false) // 配置类
	// 是否存在 org.aspectj.weaver.Advice;
	// 不存在 不生效
	@ConditionalOnClass(Advice.class)
	static class AspectJAutoProxyingConfiguration {

		@Configuration(proxyBeanMethods = false)
		@EnableAspectJAutoProxy(proxyTargetClass = false)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
				matchIfMissing = false)
		static class JdkDynamicAutoProxyConfiguration {

		}

		@Configuration(proxyBeanMethods = false)
		@EnableAspectJAutoProxy(proxyTargetClass = true)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
				matchIfMissing = true)
		static class CglibAutoProxyConfiguration {

		}

	}

	@Configuration(proxyBeanMethods = false) // 配置类

	// 判断系统里没有org.aspectj.weaver.Advice这个类就生效(目前确实没有)
	// 所以经过分析开启简单的aop
	@ConditionalOnMissingClass("org.aspectj.weaver.Advice")
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
			matchIfMissing = true)
	static class ClassProxyingConfiguration {

		ClassProxyingConfiguration(BeanFactory beanFactory) {
			if (beanFactory instanceof BeanDefinitionRegistry) {
				BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
				AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
		}

	}

}

SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先

@Bean
@ConditionalOnMissingBean // 没有这个组件,才注入
public CharacterEncodingFilter characterEncodingFilter() {
	CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
	filter.setEncoding(this.properties.getCharset().name());
	filter.setForceRequestEncoding(this.properties.shouldForce(Encoding.Type.REQUEST));
	filter.setForceResponseEncoding(this.properties.shouldForce(Encoding.Type.RESPONSE));
	return filter;
}

总结

  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定
  • 生效的配置类就会给容器中装配很多组件
  • 只要容器中有这些组件,相当于这些功能就有了
  • 定制化配置
    • 用户直接自己@Bean替换底层的组件
    • 用户去看这个组件是获取的配置文件什么值就去修改。

xxxxxAutoConfiguration —> 按需加载组件 —> xxxxProperties里面拿值 ----> application.properties

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringBoot自动配置原理简述 SpringBoot自动配置SpringBoot的一大特色,它提供了一种简洁的方式来配置应用程序。在SpringBoot中,我们可以通过添加特定的依赖来自动配置应用程序的各种组件,例如数据源、日志、Web服务等。使用自动配置可以大大简化应用程序的配置过程,减少开发人员的工作量,提高开发效率。 自动配置的实现原理是基于Spring的条件化配置机制。SpringBoot会根据应用程序的依赖和当前环境自动配置各种组件。条件化配置可以通过在类上添加@Conditional注解来实现,该注解可以指定一个条件类,只有满足该条件类的条件时,才会进行配置。例如,以下代码示例中,只有当classpath中存在H2数据库驱动程序时,才会自动配置H2的数据源。 @Configuration @ConditionalOnClass(org.h2.Driver.class) public class H2DataSourceAutoConfiguration { // 配置H2数据源 } 除了依赖条件外,SpringBoot还支持很多其他条件,例如环境条件、属性条件、Bean条件等。通过组合这些条件,可以实现更加灵活的自动配置。例如,以下代码示例中,只有当当前环境为开发环境时,才会自动配置开发环境的日志。 @Configuration @Profile("dev") public class DevLoggerAutoConfiguration { // 配置开发环境的日志 } 总之,SpringBoot自动配置机制是基于Spring的条件化配置机制实现的,它可以根据应用程序的依赖和当前环境自动配置各种组件,大大简化了应用程序的配置过程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值