Springboot---------运行原理
Posted 没昵称可用
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Springboot---------运行原理相关的知识,希望对你有一定的参考价值。
@SpringBootApplication注解详解
@SpringBootApplication注解作为Springboot的启动入口,我们会在main函数上添加@SpringBootApplication注解。该注解时一个组合注解,注解的定义如下:
@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 { }
@Documented
Documented 注解表明这个注解应该被 javadoc工具记录. 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理, 所以注解类型信息也会被包括在生成的文档中。
@Inherited
@Inherited:允许子类继承父类的注解。实例如下
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface DBTable { public String name() default ""; } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface DBTable2 { public String name() default ""; } @DBTable class Super{ private int superPrivateF; public int superPublicF; public Super(){ } private int superPrivateM(){ return 0; } public int superPubliceM(){ return 0; } } @DBTable2 class Sub extends Super{ private int subPrivateF; public int subPublicF; private Sub(){ } public Sub(int i){ } private int subPrivateM(){ return 0; } public int subPubliceM(){ return 0; } }
@SpringBootConfiguration
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration public @interface SpringBootConfiguration { }
@SpringBootConfiguration的实例如下
package com.lhkj.pluto.config; import java.util.HashMap; import java.util.Map; import org.springframework.boot.SpringBootConfiguration; import org.springframework.context.annotation.Bean; @SpringBootConfiguration public class Config { @Bean public Map createMap(){ Map map = new HashMap(); map.put("username","gxz"); map.put("age",27); return map; } }
@EnableAutoConfiguration
@ComponentScan
核心注解
@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)
@ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
@ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)
@ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)
@ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
@ConditionalOnResource(类路径是否有指定的值)
@ConditionalOnProperty(指定的属性有指定的值)
@ConditionalOnNotWebApplication(不是web应用)
@ConditionalOnBean实例如下
@Configuration public class ConditionalOnBeanConfig { @Bean public A beanA(){ return new A(); // 创建一个Bean,名称是 beanA,不需要满足什么前置条件, } @Bean @ConditionalOnBean(name="beanA") public B beanB(){ // 仅在beanFactory存在一个名称叫做beanA的bean时,当前方法初始化一个名字为beanB的bean。 return new B(); } @Bean @ConditionalOnBean public C beanC(){ //如果beanFactory不存在一个类型为C的bean,则不创建该bean。 // 如果当前项目仅有这一个 bean 配置文件,则因为 beanFactory 中不存在一个类型为C的 bean ,所以当前 // 方法定义的名称为 beanC 的 bean 并不会被初始化。 return new C(); } }
@ConditionalOnProperty实例
@ConditionalOnProperty注解判断Cofiguration是否生效,
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @Documented @Conditional({OnPropertyCondition.class}) public @interface ConditionalOnProperty { String[] value() default {}; //数组,获取对应property名称的值,与name不可同时使用 String prefix() default "";//property名称的前缀,可有可无 String[] name() default {};//数组,property完整名称或部分名称(可与prefix组合使用,组成完整的property名称),与value不可同时使用 String havingValue() default "";//可与name组合使用,比较获取到的属性值与havingValue给定的值是否相同,相同才加载配置 boolean matchIfMissing() default false;//缺少该property时是否可以加载。如果为true,没有该property也会正常加载;反之报错 boolean relaxedNames() default true;//是否可以松散匹配,至今不知道怎么使用的 }
实例
@Configuration //在application.properties配置"mf.assert",对应的值为true @ConditionalOnProperty(prefix="mf",name = "assert", havingValue = "true") public class AssertConfig { @Autowired private HelloServiceProperties helloServiceProperties; @Bean public HelloService helloService(){ HelloService helloService = new HelloService(); helloService.setMsg(helloServiceProperties.getMsg()); return helloService; } }
实战分析
属性配置
package com.kingdee.domains; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties public class HelloServiceProperties { private static final String MSG = "world"; private String msg = MSG; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
判断依据类
package com.kingdee.service; public class HelloService { private String msg; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
自动配置类
package com.kingdee; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.kingdee.domains.HelloServiceProperties; import com.kingdee.service.HelloService; @Configuration @EnableConfigurationProperties @ConditionalOnClass(HelloService.class) @ConditionalOnProperty(prefix="hello",value="enables",matchIfMissing=true) public class HelloServiceAutoConfiguration { @Autowired private HelloServiceProperties helloServiceProperties; @Bean @ConditionalOnMissingBean() public HelloService helloService(){ HelloService helloService = new HelloService(); helloService.setMsg(helloServiceProperties.getMsg()); return helloService; } }
@EnableConfigurationProperties在SpringBoot的注释中是这样说明的:为带有@ConfigurationProperties注解的Bean提供有效的支持。这个注解可以提供一种方便的方式来将带 @ConfigurationProperties注解的类注入为Spring容器的Bean。将配置文件中对应的值和指定类绑定起来;并把HttpEncodingProperties加入到ioc容器中。
创建spring.factories
在resources下面创建META-INF/spring.factories, 然后在文件中把第三步的类配置进去,如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.kingdee.HelloServiceAutoConfiguration
封装成包
分装成jar包后,就可以将该jar包在其他项目中引用。
以上是关于Springboot---------运行原理的主要内容,如果未能解决你的问题,请参考以下文章