springBoot1-自动装配

微服务

先看完 微服务和组件化微服务的未来

初探:springBoot的自动装配

在pom.xml中父工程下的

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
  </parent>

spring-boot-dependencies 帮我们管理了对所有jar包的版本依赖(在使用jar包时不需要指定即可使用,可以避免jar包版本冲突)

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath>../../spring-boot-dependencies</relativePath>
</parent>

例如

<properties>
        <activemq.version>5.15.3</activemq.version>
        <antlr2.version>2.7.7</antlr2.version>
        <appengine-sdk.version>1.9.63</appengine-sdk.version>
        <artemis.version>2.4.0</artemis.version>
        ......................................
 <properties>
pom.xml中的启动器

启动器的作用?例如我们导入了web的启动器
spring-boot-starter-web
即可支持全栈式Web开发,包括Tomcat和spring-webmvc。

 <!--启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
       </dependency>

springBoot2.2版本所有的的启动器

主类SpringBootApplication

@SpringBootApplication标注这个类是一个springboot的应用,其也是一个组合注解,该注解下的所有注解将会被导入Spring容器中。
其注解包括了4个标准注解、2个扫描注解、一个配置类注解和一个开启自动配置类注解。

//@SpringBootApplication标注这个类是一个springboot的应用
@SpringBootApplication
public class SpringbootApplication {
    public static void main(String[] args) {
        //通过反射获得SpringbootApplication的对象启动它
        SpringApplication.run(SpringbootApplication.class, args);
    }
}

关于java注解和自定义注解之后会补上

@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) })
@ConfigurationPropertiesScan
public @interface SpringBootApplication {
}

注解

@SpringBootConfiguration  :声明该类是一个SpringBoot的配置类
	@Configuration  :生命该类是spring的配置类
		@Component:该类加入了spring容器 是一个spring组件
		
@EnableAutoConfiguration:开启自动装填配置
	@AutoConfigurationPackage :自动装填配置包
		@Import(AutoConfigurationPackages.Registrar.class) :自动配置包注册
	@Import(AutoConfigurationImportSelector.class) :自动配置导入选择器

注解
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
其实引入了两个类:
AutoConfigurationPackages.Registrar
AutoConfigurationImportSelector

@AutoConfigurationPackage会将我们 注解@ComponentScan()扫描当前启动类及其子类所有的注解并加入我们的Spring容器中

@Import(AutoConfigurationImportSelector.class)自动配置选择器如何自动装配

@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
				.loadMetadata(this.beanClassLoader);
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
				annotationMetadata);
		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
	}

首先会判断 调用isEnable() 方法 判断是否开启自动装配 (判断EnableAutoConfiguration是否开启默认开启true)

@Override
	public Class<? extends Group> getImportGroup() {
		return AutoConfigurationGroup.class;
	}
	protected boolean isEnabled(AnnotationMetadata metadata) {
		if (getClass() == AutoConfigurationImportSelector.class) {
			return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true);
		}
		return true;
	} 

该类是如何自动装配最优设置?

AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,

getAutoConfigurationEntry() 方法用于获取自动装配实体类

/**
	 * Return the {@link AutoConfigurationEntry} based on the {@link AnnotationMetadata}
	 * of the importing {@link Configuration @Configuration} class.
	 * @param autoConfigurationMetadata the auto-configuration metadata
	 * @param annotationMetadata the annotation metadata of the configuration class
	 * @return the auto-configurations that should be imported
	 */
	protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
			AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
		configurations = removeDuplicates(configurations);
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = filter(configurations, autoConfigurationMetadata);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}

在该类中有一步getCandidateConfigurations()方法 用于获取候选配置

List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);

首先通过方法
List configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());去加载自动装配的配置文件 也就是 spring.factories

以下是加载过程
 public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
        String factoryTypeName = factoryType.getName();
        return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
    }

    private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
        if (result != null) {
            return result;
        } else {
            try {
                Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
                LinkedMultiValueMap result = new LinkedMultiValueMap();

                while(urls.hasMoreElements()) {
                    URL url = (URL)urls.nextElement();
                    UrlResource resource = new UrlResource(url);
                    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                    Iterator var6 = properties.entrySet().iterator();

                    while(var6.hasNext()) {
                        Entry<?, ?> entry = (Entry)var6.next();
                        String factoryTypeName = ((String)entry.getKey()).trim();
                        String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                        int var10 = var9.length;

                        for(int var11 = 0; var11 < var10; ++var11) {
                            String factoryImplementationName = var9[var11];
                            result.add(factoryTypeName, factoryImplementationName.trim());
                        }
                    }
                }

                cache.put(classLoader, result);
                return result;
            } catch (IOException var13) {
                throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
            }
        }
    } 

classLoader.getResources(“META-INF/spring.factories”) : 获取项目资源
ClassLoader.getSystemResources(“META-INF/spring.factories”); 获取系统资源
从文件META-INF/spring.factories中获取
spring.factories自动装配文件位置
在这里插入图片描述
这些将要被装入IOC的Bean命名有一定的规律,每一个×××AutoConfiguration 都作为容器中的一个组件,以下就是web的组件(部分)
在这里插入图片描述 最后判断自动配置的信息是否为空,为空抛出异常。在这里插入图片描述至此@Import(AutoConfigurationImportSelector.class)装配结束
但是我们明明将 spring.factories 中的所有组件都加入了Spring容器中为什么该组件还是报红?
在这里插入图片描述

注解:

@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class })
只有满足{ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class }中所有的条件时该组件才会被加载到容器中。
为什么我们WEB的组件可以被加载到容器中,因为我们在pom中加入了,web启动器

 		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

注解 @ConditionalOnClass 之后再补上
springBoot的自动装配 待续。。。。。。。。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目名称:Java中的简单游戏和应用程序 项目简介: 简单游戏和应用程序是一个Java项目。该项目包含23个不同的Java制作的应用程序和游戏。项目中还包括记事本、拼图等简单应用程序。这是一个单框架程序,你可以选择并运行你希望运行的程序。要运行此项目,你必须在系统上安装JDK路径。 项目简介: 这是一个简单的游戏和应用程序集合,由不同的Java应用程序组成,使该项目独特。你可以选择要运行的程序。如果你想运行记事本,只需在应用程序中点击选项。在记事本中,你可以轻松进行写作,可以处理任何你想要的文本样式。 此外,该项目还包括游戏和测验,例如井字棋和拼图游戏。项目中还提供了字数统计功能。你可以输入任意多的文本,之后可以统计段落中的字数。你还可以玩数独和太空侵略者游戏。不仅如此,你还可以在这个项目中运行不同的应用程序。 项目功能: 记事本:进行文本写作和格式处理。 拼图游戏:挑战你的智力。 井字棋:经典的两人游戏。 字数统计:统计输入文本的字数。 数独:经典的数字填空游戏。 太空侵略者:经典的射击游戏。 其他应用程序和游戏:总计23个不同的程序。 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值