Spring IoC容器添加组件的方式
小编在博文《Spring Bean是什么》中介绍了Bean的基本概念,这里详细地介绍如何注册bean。
1、包扫描@ComponentScan+组件标注注解
适用场景:可以通过该方式把我们自己写的组件加载到容器中。使用注解@CompentScan进行包扫描,将带有@Controller、@Service、@Respository和@Compent注解的类扫描到IoC容器中。
包扫描不是必须的,指定包名后以指定的包名为准,比如指定包名为a:@ComponentScan("a"),即使b包中有标注@Controller等注解的bean,它也不注册。包扫描注解除了默认的方法value(),还包括如下方法:
basePackages(): 指定扫描的包名(前缀)。
basePackageClasses():如果指定为A.class,那么会扫描A类所在包的类。
includeFilters():将所指定的类注入容器。
excludeFilters():将所指定的类排除。
2、通过@Bean导入组件
适用于导入第三方组件的类。 可以放在方法和注解上,一般放在标有@Configuration类中的方法上。更多详细信息请戳我。
3、通过@Import导入组件
需要注意的是,被导入组件的ID默认是全类名。
3.1、导入类
@Configuration @Import(value = {Person.class, Car.class})
public class MainConfig {
}
3.2、导入ImportSeletor类实现组件
public class MyImportSelector implements ImportSelector {
//可以获取导入类的注解信息
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.my.testimport.compent.Car"};
}
}
@Configuration
@Import(value = {Person.class, Car.class, MyImportSelector.class})
public class MainConfig {
}
Spring Boot的自动注入就是用了这种方式。
3.3、导入实现 ImportBeanDefinitionRegister接口类的组件
public class MyBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//创建一个bean定义对象
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Cat.class);
//把bean定义对象导入到容器中
registry.registerBeanDefinition("cat",rootBeanDefinition);
}
}
@Configuration
@Import(value = {Person.class, Car.class, MyImportSelector.class, MyBeanDefinitionRegister.class})
public class MainConfig {
}
AOP的实现注册类AutoProxyRegistrar就是实现了ImportBeanDefinitionRegister类。
4、通过实现FacotryBean接口注册组件
@Component
public class CarFactoryBean implements FactoryBean<Car> {
//返回bean的对象
@Override
public Car getObject() throws Exception {
return new Car();
}
//返回bean的类型
@Override
public Class<?> getObjectType() {
return Car.class;
}
//是否为单利
@Override
public boolean isSingleton() {
return true;
}
}
Spring获取对象时,返回的是getObject方法返回的对象,要想返回fanctoryBean对象,需要在获取对象名前加上&符号,即 getBean("carFactoryBean" )
返回car对象,getBean("&carFactoryBean" )
返回CarFactoryBean 对象。
public class App {
public static void main(String[] args) {
//读取注解
ApplicationContext applicationContext1 = new AnnotationConfigApplicationContext(MyConfig2.class);
String[] names= applicationContext1.getBeanDefinitionNames();
for (String name:names){
System.out.println(name); //这里输出的类的全类名
}
}
}
结束语
那么大家对于这件事都是怎么看的呢?欢迎在文章下方留言讨论!三人行必有我师焉!小编每条都会仔仔细细地看。