spring之组件注册

基于注解和类的组件注册

@Conditional

作用:按照一定的条件进行判断,如果满足条件的话就给spring容器中注册bean

​ 该注解既可以标注到方法上面,也可以标注到类上面(只有满足条件时,当前类中配置的bean才能注册)

属性:Class[] value()

​ value属性需要创建一个实现Condition接口的类并且重写其中的matches方法

public class testCondition implements Condition {
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return false;
    }
}

示例:想要实现如果当前是在windows系统下就注册bill如果是在linux下就注册linus

MyConfig配置类

@Configuration
@ComponentScan("com.zl")
public class MainConfig {

    @Bean("bill")
    @Conditional(WindowsCondition.class)
    public Person person01(){
        return new Person("bill",50);
    }
    @Bean("linus")
    @Conditional(LinuxCondition.class)
    public Person person02(){
        return new Person("linus",49);
    }
}

WindowsCondition

public class WindowsCondition implements Condition {
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        String property = environment.getProperty("os.name");
        if (property.contains("Windows")){
            return true;
        }
        return false;
    }
}

LinuxCondition

public class LinuxCondition implements Condition {
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        String property = environment.getProperty("os.name");
        if (property.contains("Linux")){
            return true;
        }
        return false;
    }
}

测试类

public class IocTest {
    private ApplicationContext applicationContext;

    @Before
    public void init(){
        applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
    }
    @Test
    public void testConditional(){
        String[] names = applicationContext.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
}
//因为是在windows环境下运行,所以IOC容器中注册的就是bill

@Import()

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {

    /**
     * {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
     * or regular component classes to import.
     */
    Class[] value();

}

我们这里来分析一下{@link ImportBeanDefinitionRegistrar}以这种方式来注册bean

作用:我们可以通过给@Import注解传入一个实现了ImportBeanDefinitionRegistrar的类来完成注册bean

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    /**
     * AnnotationMetadata: 当前标注@Import注解类的所有注解信息
     * BeanDefinitionRegistry: BeanDefinition注册类
     * @param importingClassMetadata
     * @param registry
     */
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        registry.registerBeanDefinition("person",new RootBeanDefinition(Person.class));
    }
}

FactroyBean

作用:我们可以创建一个实现FactoryBean接口的工厂类,并且实现其中的方法,从而完成bean的注册

PersonFactoryBean工厂类

public class PersonFactoryBean implements FactoryBean {
    //返回一个Person对象并且添加到容器当中
    public Object getObject() throws Exception {
        return new Person();
    }
    //返回bean对象的类型
    public Class getObjectType() {
        return Person.class;
    }
    //创建的bean对象是否单例?
    public boolean isSingleton() {
        return false;
    }
}

在MyConfig中配置PersonFactoryBean

@Bean
public PersonFactoryBean personFactoryBean(){
    return new PersonFactoryBean();
}

测试类

@Test
    public void testPersonFactoryBean(){
        Object bean1 = applicationContext.getBean("personFactoryBean");
        System.out.println(bean1.getClass());
        Object bean2 = applicationContext.getBean("&personFactoryBean");
        System.out.println(bean2.getClass());
    }
    /**
     * 通过测试我们发现当我们从IOC容器中获取personFactroyBean对象时,得到的是我们通过              
     * PersonFactroyBean中的 getObject()方法创建的Person对象
     *
     * 如果想要获取到PersonFactoryBean对象的话就要在name属性前加上&
     */

你可能感兴趣的:(spring之组件注册)