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());
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章