主入口代码
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args) {
// 让Spring应用启动起来,这个原理就是启动spring的主入口
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
1@SpringBootApplication:
设置:这个类是SpringBoot的主配置类(HelloWorldMainApplication ),SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;
SpringApplication.run(主配置类的类对象,main方法的参数);这个功能就像很久以前Java的启动类,args就是启动类参数。
@SpringBootApplication类
1.1@SpringBootConfiguration
容器初始化的时候会读取配置类信息到容器中,相当于配置web.xml读取配置文件
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
Spring Boot的配置类,标注在某个类上,表示这是一个Spring Boot的配置类;
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration//配置类上来标注这个注解,初始化配置类的信息到容器中 public @interface SpringBootConfiguration { }
1.11@Configuration
用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
换句话说:使用这个注解将将某个包下的配置类初始化到容器中。
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Configuration { String value() default ""; }
1.12@EnableAutoConfiguration:
开启自动配置功能,打个比方说,项目中集成redis,那么一定要有redis.xml的配置。当我们开启这个注解后,它会去自动配置redis的配置信息。
@SuppressWarnings("deprecation") @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration {
1.121@AutoConfigurationPackage
自动配置包,相当于spring扫描包的功能(
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import(AutoConfigurationPackages.Registrar.class)//将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器; public @interface AutoConfigurationPackage { }
@Import(AutoConfigurationPackages.Registrar.class)//将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
@Order(Ordered.HIGHEST_PRECEDENCE) static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports { @Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { //注册主入口类的包名 register(registry, new PackageImport(metadata).getPackageName()); }
1.122@Import(EnableAutoConfigurationImportSelector.class)
给容器中导入选择器中的组件。
EnableAutoConfigurationImportSelector:导入的组件选择器;
将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;
会给容器中导入非常多的自动配置类(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件,并配置好这些组件。
换句话说:当我们需要redis组件的时候,使用这个注解,redis的所有配置就会导入进来。
@Deprecated public class EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector { @Override protected boolean isEnabled(AnnotationMetadata metadata) { if (getClass().equals(EnableAutoConfigurationImportSelector.class)) { return getEnvironment().getProperty( EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true); } return true; } }
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List<String> 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;
}
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
try {
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
ArrayList result = new ArrayList();
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
String factoryClassNames = properties.getProperty(factoryClassName);
result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
}
retur
META-INF/spring.factories
这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作;
比如说:这里面有redis配置。
@Configuration
@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {
/**
* Redis connection configuration.
*/
@Configuration
@ConditionalOnClass(GenericObjectPool.class)
protected static class RedisConnectionConfiguration {
private final RedisProperties properties;
private final RedisSentinelConfiguration sentinelConfiguration;
private final RedisClusterConfiguration clusterConfiguration;
public RedisConnectionConfiguration(RedisProperties properties,
ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
ObjectProvider<RedisClusterConfiguration> clusterConfiguration) {
this.properties = properties;
this.sentinelConfiguration = sentinelConfiguration.getIfAvailable();
this.clusterConfiguration = clusterConfiguration.getIfAvailable();
}
@Bean
@ConditionalOnMissingBean(RedisConnectionFactory.class)
public JedisConnectionFactory redisConnectionFactory()
throws UnknownHostException {
return applyProperties(createJedisConnectionFactory());
}
RedisProperties.class
@ConfigurationProperties(prefix = "spring.redis") public class RedisProperties { /** * Database index used by the connection factory. */ private int database = 0; /** * Redis url, which will overrule host, port and password if set. */ private String url; /** * Redis server host. */ private String host = "localhost"; /** * Login password of the redis server. */ private String password;