给容器中注册组件(bean)的几种方式
(一)包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)有局限,只能给自己写的类加注解
【使用方式】
- 直接在类上加注解即可
(二)@Bean【导入的第三方包里面的组件】
Person.java
public class Person {
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
使用@Bean()方式注入
@Bean("bill")
public Person person01(){
return new Person("Bill Gates",62);
}
(三)@import【快速给容器中导入一个组件】
【优势】
- 每次都是用@Bean()注解,无参构造器创建一个对象有点麻烦
- 使用这个注解可以直接快速给容器中导入一个组件
【使用方式】
- @import(要导入到容器中的组件):容器中就会自动注册这个组件,id默认是全类名
@import({Red.class,Color.class})
public class MainConfig2 {
}
测试
public class IOCTest {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
@Test
public void testimport(){
printBeans(applicationContext);
}
private void printBeans(AnnotationConfigApplicationContext applicationContext) {
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
结果
- importSelector:返回需要导入的组件的全类名数组
MyimportSelector.java 需要导入的组件的全类名
public class MyimportSelector implements importSelector {
@Override
public String[] selectimports(Annotationmetadata importingClassmetadata) {
return new String[]{"com.example.study.bean.Blue","com.example.study.bean.Pink"};
}
}
配置类
@import({MyimportSelector.class})
public class MainConfig2 {
}
结果
- importBeanDefinitionRegistrar 手动注册bean到容器中
当容器中有Pink.class和Blue.class才将RainBow.class放到容器
public class MyimportBeanDefinitionRegistrer implements importBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(Annotationmetadata importingClassmetadata, BeanDefinitionRegistry registry) {
boolean definition = registry.containsBeanDefinition("com.example.study.bean.Pink");
boolean definition1 = registry.containsBeanDefinition("com.example.study.bean.Blue");
if (definition && definition1){
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);
registry.registerBeanDefinition("rainBow",rootBeanDefinition);
}
}
}
配置类
@import({Pink.class,Blue.class,MyimportBeanDefinitionRegistrer.class})
public class MainConfig2 {
}
结果
(四)使用Spring提供的FactoryBean(工厂bean)
- 默认获取到的是工厂bean调用getObject创建的对象
- 要获取工厂Bean本身,我们需要给id前加一个&
ColorFactoryBean .class
public class ColorFactoryBean implements FactoryBean{ @Override public Color getObject() throws Exception { return new Color(); } @Override public Class> getObjectType() { return Color.class; } @Override public boolean isSingleton() { return true; } }
配置类MainConfig2 .java,注入bean工厂
public class MainConfig2 {
@Bean
private ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}
}
IOCTest.java测试
public class IOCTest {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
@Test
public void testimport(){
Object colorFactoryBean = applicationContext.getBean("colorFactoryBean");
System.out.println("工厂类getObject创建的对象====="+colorFactoryBean.getClass());
Object colorFactoryBean2 = applicationContext.getBean("&colorFactoryBean");
System.out.println("获取工厂Bean本身====="+colorFactoryBean2.getClass());
}
}
结果



