Spring容器中注入組件的幾種方式

  1. 包掃描+註解
    針對我們自己開發的類,一般採用包掃描+註解的方式注入,類似@Controller @Service…等等這些註解。實例如下:
@Configuration
@ComponentScans(value = {
		//定義掃描的包
        @ComponentScan(basePackages = {"Spring"}
        })
})
public class MyConfig {
}
@Controller
public class PersonController {
}
  1. @Bean
    該方式一般快速導入第三方包裏面的組件,假定Person是第三方包,只要調用無參構造方法就可以
  @Bean
    //默認用方法名作爲ID
    public Person person() {
        return new Person();
    }
  1. @Import
    3.1. 該註解可以快速給容器中導入組件,但是要注意的是,導入的組件的ID默認是全類名
//通過這種方式導入Color和Red類
@Configuration
@Import({Color.class, Red.class})
public class MyConfig2 {
}
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);  //這裏輸出的類的全類名
        }
    }
}

3.2. 也可以通過實現ImportSelector裏面的方法來導入

@Configuration
@Import({MyImportSelector.class})
public class MyConfig2 {
}
public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
    //根據全路徑也可以導入
        String[] str = new String[]{
                "Spring.imports.Blue",
                "Spring.imports.Yellow"
        };
        return str;
    }
}

3.3. 也可以通過實現BeanDefinitionRegistrar裏面的方法來導入,這個種方式可以指定組件的名稱

@Configuration
@Import({MyImportBeanDefinitionRegistrar.class})
public class MyConfig2 {

}
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
        registry.registerBeanDefinition("rainBow",beanDefinition);
    }
}
  1. 使用FactoryBean 注入(工廠Bean)
    該方式是實現FactoryBean<T>並且實現其中的方法,返回工廠時返回的是getObject方法中返回的內容。需要獲取工廠Bean本身需要我們給id的前面加一個&
public interface FactoryBean<T> {
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
    @Nullable
    T getObject() throws Exception;
    @Nullable
    Class<?> getObjectType();
    default boolean isSingleton() {
        return true;
    }
}
//自定義的FactoryBean
public class  MyFactoryBean implements FactoryBean<Color> {
    @Override
    public Color getObject() throws Exception {
        return new Color();
    }

    @Override
    public Class<?> getObjectType() {
        return Color.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}
//注入Factory
@Configuration
public class MyConfig2 {
    @Bean("color")
    public MyFactoryBean  getFactoryBean(){
        return new MyFactoryBean();
    }
}

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);
        }
        Object color = applicationContext1.getBean("color"); 
        //獲取到的組件是Spring.imports.Color
        System.out.println(color.getClass());
        //獲取到的就是工廠自身的類
         color = applicationContext1.getBean("&color");
        System.out.println(color.getClass());
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章