一,ComponentScan注解的默认扫描范围
ComponentScan注解的默认扫描范围是启动程序XxxApplication.java所在目录及其下的所有子包。
为了方便理解,我们看一下下面这个图片。
这个项目中的启动类是:SpringbootApplication.java
该启动类所在的目录是:springboot
那么ComponentScan注解的默认扫描范围是:springboot目录及其下面的所有子包。
二,如何修改ComponentScan注解的扫描范围
ComponentScan注解即可以扫描包,也可以扫描指定的类。我们只需要指定一个包扫描的路径,就可以实现更改包扫描路径的功能了。
1,ComponentScan注解扫描包。
@ComponentScan({"com.company.user","com.company.service"})
2,ComponentScan注解扫描类。
@ComponentScan(basePackageClasses={XxxService.class})
三,ComponentScan注解
ComponentScan注解中定义了12个属性,我们下面详细来看一下。我们的讨论是基于java8的,spring-context的版本是4.3.7。
1,String[]value()default{};
指定包扫描路径,value属性的值,就是项目中的一个具体路径。value属性的类型是String数组,也就是支持一次指定多个包扫描路径。这个属性上面添加了一个注解,@AliasFor("basePackages"),这个注解的意思就是说,value这个属性等价于basePackages属性。关于basePackages属性,下面会讲到。
2,String[]basePackages()default{};
指定包扫描路径,basePackages属性的值,就是项目中的一个具体路径。basePackages属性的类型是String数组,也就是支持一次指定多个包扫描路径。basePackages属性上面添加了一个注解,@AliasFor("value"),这个注解的意思就是说,basePackages这个属性等价于value属性。
3,Class?[]basePackagesClasses()default{};
扫描具体的类。basePackagesClasses属性的类型是Class数组,也就是说支持同时指定多个扫描类。
4,Class?extendsBeanNameGeneratornameGenerator()defaultBeanNameGenerator.class;
配置beanName生成器,默认是BeanNameGenerator。一般情况下,我们都是使用默认的beanName生成器,但是Spring实现了beanName生成器的可配置。
5,Class?extendsScopeMetaDataResolverscopeResolver()defaultAnnotationScopeMetaDataResolver.class;
处理检测到的bean的scope范围。什么意思呢?我们都知道spring的bean是有作用域的,默认是singleton,这个默认值就是在ScopeMetaData类中指定的:
privateStringscopeName="singleton";
这个属性也是可选配置,默认的处理bean作用域的实现类是AnnotationScopeMetaDataResolver.class。源码比较简单,就是取注解上获取指定的scope的value值,如果没有配置,就是用默认的singleton。
6,ScopedProxyModescopedProxy()defaultScopedProxyMode.DEFAULT;
是否为检测到的组件生成代理。
ScopedProxyMode是一个枚举类,可选值有四个:DEFAULT,NO,INTERFACES,TARGET_CLASS。
7,StringresourcePattern()default"""**/*.class";
控制符合组件检测条件的类文件,默认是包扫描下的?**/*.class。
8,booleanuseDefaultFilters()defaulttrue;
是否对含有以下注解的类开启检测,默认是开启的。
@Component
@Repository
@Service
@Controller
9,ComponentScan.Filter[]includeFilters()default{};
指定某些Filter扫描到的类。听起来有些费劲,说白了就是指定了类型,扫描指定的这些类型。可选类型有5种,定义在枚举类FilterType中:
第一种:ANNOTATION
第二种:ASSIGNABLE_TYPE
第三种:ASPECTJ
第四种:REGEX,正则表达式。
第五种:CUSTOM,自定义类型。
10,ComponentScan.Filter[]excludeFilters()default{};
排除过滤器扫描的的类。
11,booleanlazyInit()defaultfalse;
扫描到的类是否开启懒加载,默认不开启。
12,
@Retention(RetentionPolicy.RUNTIME);
@Target({})
public@interfaceFilter{
FilterTypetype()defaultFilterType.ANNOTATION;
@AliasFor("classes")
Class?[]value()default{};
@AliasFor("value")
Class?[]classes()default{};
String[]pattern()default{};
}
SpringBoot最核心的25个注解,都是干货!
SpringBoot最核心的25个注解
1、@SpringBootApplication
这是SpringBoot最最最核心的注解,用在SpringBoot主类上,标识这是一个SpringBoot应用,用来开启SpringBoot的各项能力。
其实这个注解就是@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan这三个注解的组合,也可以用这三个注解来代替@SpringBootApplication注解。
2、@EnableAutoConfiguration
允许SpringBoot自动配置注解,开启这个注解之后,SpringBoot就能根据当前类路径下的包或者类来配置SpringBean。
如:当前类路径下有Mybatis这个JAR包,MybatisAutoConfiguration注解就能根据相关参数来配置Mybatis的各个SpringBean。
3、@Configuration
这是Spring3.0添加的一个注解,用来代替applicationContext.xml配置文件,所有这个配置文件里面能做到的事情都可以通过这个注解所在类来进行注册。
4、@SpringBootConfiguration
这个注解就是@Configuration注解的变体,只是用来修饰是SpringBoot配置而已,或者可利于SpringBoot后续的扩展。
5、@ComponentScan
这是Spring3.1添加的一个注解,用来代替配置文件中的component-scan配置,开启组件扫描,即自动扫描包路径下的@Component注解进行注册bean实例到context中。
前面5个注解可以在这篇文章《SpringBoot最核心的3个注解详解》中了解更多细节的。
6、@Conditional
这是Spring4.0添加的新注解,用来标识一个SpringBean或者Configuration配置文件,当满足指定的条件才开启配置。
7、@ConditionalOnBean
组合@Conditional注解,当容器中有指定的Bean才开启配置。
8、@ConditionalOnMissingBean
组合@Conditional注解,和@ConditionalOnBean注解相反,当容器中没有指定的Bean才开启配置。
9、@ConditionalOnClass
组合@Conditional注解,当容器中有指定的Class才开启配置。
10、@ConditionalOnMissingClass
组合@Conditional注解,和@ConditionalOnMissingClass注解相反,当容器中没有指定的Class才开启配置。
11、@ConditionalOnWebApplication
组合@Conditional注解,当前项目类型是WEB项目才开启配置。
当前项目有以下3种类型。
enumType{
}
12、@ConditionalOnNotWebApplication
组合@Conditional注解,和@ConditionalOnWebApplication注解相反,当前项目类型不是WEB项目才开启配置。
13、@ConditionalOnProperty
组合@Conditional注解,当指定的属性有指定的值时才开启配置。
14、@ConditionalOnExpression
组合@Conditional注解,当SpEL表达式为true时才开启配置。
15、@ConditionalOnJava
组合@Conditional注解,当运行的JavaJVM在指定的版本范围时才开启配置。
16、@ConditionalOnResource
组合@Conditional注解,当类路径下有指定的资源才开启配置。
17、@ConditionalOnJndi
组合@Conditional注解,当指定的JNDI存在时才开启配置。
18、@ConditionalOnCloudPlatform
组合@Conditional注解,当指定的云平台激活时才开启配置。
19、@ConditionalOnSingleCandidate
组合@Conditional注解,当指定的class在容器中只有一个Bean,或者同时有多个但为首选时才开启配置。
20、@ConfigurationProperties
用来加载额外的配置(如.properties文件),可用在@Configuration注解类,或者@Bean注解方法上面。
21、@EnableConfigurationProperties
一般要配合@ConfigurationProperties注解使用,用来开启对@ConfigurationProperties注解配置Bean的支持。
22、@AutoConfigureAfter
用在自动配置类上面,表示该自动配置类需要在另外指定的自动配置类配置完之后。
如Mybatis的自动配置类,需要在数据源自动配置类之后。
23、@AutoConfigureBefore
这个和@AutoConfigureAfter注解使用相反,表示该自动配置类需要在另外指定的自动配置类配置之前。
24、@Import
这是Spring3.0添加的新注解,用来导入一个或者多个@Configuration注解修饰的类,这在SpringBoot里面应用很多。
25、@ImportResource
这是Spring3.0添加的新注解,用来导入一个或者多个Spring配置文件,这对SpringBoot兼容老项目非常有用,因为有些配置无法通过JavaConfig的形式来配置就只能用这个注解来导入。
欢迎Java工程师朋友们加入Java高并发:957734884,群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!
springboot增加@ComponentScan后就扫描不到其他包了参考如下:
扫描多个包
@ComponentScan("com.a,com.b")
public?class?APP?{
????public?static?void?main(String[]?args)?{
????????SpringApplication.run(APP.class,?args);
????}
}
springboot项目scanBasePackages和exclude迁移到配置文件在实际开发中想把@SpringBootApplication扫描包scanBasePackages和排除功能exclude放到配置文件@Configuration中,方便打jar包(不要@SpringBootApplication)……搜索查询了很久,没有找到方法手动捂脸……最后……如下
@SpringBootApplication(scanBasePackages={"com.demo.workflow","com.demo.xiaoxiao.swagger"},,exclude={SecurityAutoConfiguration.class})迁移到config配置文件
注意如下方式迁移是无效的
@ComponentScan(basePackages={"com.demo.workflow","com.demo.skull","org.flowable.ui.modeler","org.flowable.ui.common"}
,[email protected](type=FilterType.ASSIGNABLE_TYPE,classes=SecurityAutoConfiguration.class)
)
为什么这么迁移?其实很简单,我们看下注解源码就知道了,截取一部分
scanBasePackages对应的刚好是@ComponentScan
exclude对应的刚好是@EnableAutoConfiguration(exclude
所以将启动类的配置更改到配置中心如上
SpringBoot启动分析SpringApplication.run方法中,实例化一个SpringApplication对象,并调用该对象的run方法。
在SpringApplication构造函数中,主要完成了这样两件事:
在run()中主要完成如下几项工作:
在refreshContext方法中实现Ioc容器的初始化和Ioc的依赖注入。其中,在invokeBeanFactoryPostProcessors()方法中完成了IoC容器初始化过程的三个步骤。
第一步:Resource定位
在SpringBoot中,我们都知道他的包扫描是从主类所在的包开始扫描的,prepareContext()方法中,会先将主类解析成BeanDefinition,然后在refresh()方法的invokeBeanFactoryPostProcessors()方法中解析主类的BeanDefinition获取basePackage的路径。这样就完成了定位的过程。其次SpringBoot的各种starter是通过SPI扩展机制实现的自动装配,SpringBoot的自动装配同样也是在invokeBeanFactoryPostProcessors()方法中实现的。还有一种情况,在SpringBoot中有很多的@EnableXXX注解,细心点进去看的应该就知道其底层是@Import注解,在invokeBeanFactoryPostProcessors()方法中也实现了对该注解指定的配置类的定位加载。
常规的在SpringBoot中有三种实现定位,第一个是主类所在包的,第二个是SPI扩展机制实现的自动装配(比如各种starter),第三种就是@Import注解指定的类。
第二步:BeanDefinition的载入
在第一步中说了三种Resource的定位情况,定位后紧接着就是BeanDefinition的分别载入。所谓的载入就是通过上面的定位得到的basePackage,SpringBoot会将该路径拼接成:classpath:org/springframework/boot/demo//.class这样的形式,然后一个叫做PathMatchingResourcePatternResolver的类会将该路径下所有的.class文件都加载进来,然后遍历判断是不是有@Component注解,如果有的话,就是我们要装载的BeanDefinition。大致过程就是这样的了。
TIPS:@Configuration,@Controller,@Service等注解底层都是@Component注解,只不过包装了一层罢了。
第三步:注册BeanDefinition
这个过程通过调用上文提到的BeanDefinitionRegister接口的实现来完成。这个注册过程把载入过程中解析得到的BeanDefinition向IoC容器进行注册。通过上文的分析,我们可以看到,在IoC容器中将BeanDefinition注入到一个ConcurrentHashMap中,IoC容器就是通过这个HashMap来持有这些BeanDefinition数据的。比如DefaultListableBeanFactory中的beanDefinitionMap属性。
invokeBeanFactoryPostProcessors方法中主要通过ConfigurationClassPostProcessor完成IoC容器初始化的过程。
registerBeanPostProcessors方法中注册了AutowiredAnnotationBeanPostProcessor,registerBeanPostProcessors方法中对bean进行初始化时会调用AutowiredAnnotationBeanPostProcessor的接口实现@Autowired,完成Ioc的注入。
参考:
springboot配置文件注解springboot使用一个全局配置文件,配置文件的名字是固定的:
application.properties或application.yml
@ConfigurationProperties:将全局配置文件的属性值,映射到SpringBoot组件上
@Value:从全局配置文件中读取属性,映射到组件上
@PropertySource:加载指定的配置文件。可以配合@Value和@ConfigurationProperties使用。默认只能加载XML文件,若需要加载yml文件需要实现DefaultPropertySourceFactory的createPropertySource()方法,并在注解中声明。springboot中yml、yaml对应的加载类为YamlPropertySourceLoader.
@ImportResource:加载自定义的SpringXML配置文件
SpringBoot不推荐使用这种方式,推荐使用全注解(JavaConfig)的方式。
SpringBoot会扫描当前包和所有子包的注解配置到容器中。
logo设计
创造品牌价值
¥500元起
APP开发
量身定制,源码交付
¥2000元起
商标注册
一个好品牌从商标开始
¥1480元起
公司注册
注册公司全程代办
¥0元起
查
看
更
多