spring boot 给容器中注册组件包括:
1、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)【多用于自己写的类】
2、在配置文件中(@Configuration)使用@Bean注解 【多用于导入第三方包里面的组件,或是需要对组件做其他特殊操作】
3、@Import【快速给容器中导入一个组件】
- @Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
- ImportSelector:返回需要导入的组件的全类名数组;
- ImportBeanDefinationRegistrar:手动注册bean到容器中
4、使用spring提供的FactoryBean(工厂Bean)
- 默认获取的是工厂bean调用getObject创建的对象
- 要获取工厂Bean本身,我们需要在id前面加一个& 因为在BeanFactory中专门定义了一个符号 &,来区分获取factoryBean本身和它所创建的对象
/**
* Used to dereference a {@link FactoryBean} instance and distinguish it from
* beans <i>created</i> by the FactoryBean. For example, if the bean named
* {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
* will return the factory, not the instance returned by the factory.
*/
String FACTORY_BEAN_PREFIX = "&";
在写spring boot项目时,发现使用了@SpringBootApplication注解后,所有使用组件标注的类已经注册进容器中,但是并没有看到@ComponentScan注解。阅读@SpringBootApplication源码
package org.springframework.boot.autoconfigure;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.annotation.AliasFor;
@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 {
@AliasFor(annotation = EnableAutoConfiguration.class, attribute = "exclude")
Class<?>[] exclude() default {};
@AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName")
String[] excludeName() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
}
可以看到 @SpringBootApplication = @SpringBootConfiguration(=@Configuration) + @EnableAutoConfiguration + @ComponentScan,因此可以进行自动扫描。
在上述源码中看到频繁出现的@AliasFor注解。如下面所示:
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
上述代码的含义就是:
使用@SpringBootApplication(scanBasePackageClasses={xxx.class,xxx.class})和使用@ComponentScan(basePackageClasses={xxx.class,xxx.class})是一样的效果,即在SpringBootApplication中创建了一个scanBasePackageClasses这样的属性,为了让这个属性等同于@ComponentScan属性中的basePackageClasses属性,所以使用@AliasFor标签,分别设置了value(即作为哪个属性的别名)和annotation(即作为哪个注解)