IOC注入Bean的配置方式

185 阅读1分钟

了解常用的Bean注入方式是必备的知识点,它可以帮助我们配置相关属性,本篇文章已实例来说明。

XML方式配置

public class Student {

    private String name;

    private int age;

    private List<String> classList;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<String> getClassList() {
        return classList;
    }

    public void setClassList(List<String> classList) {
        this.classList = classList;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + ''' +
                ", age=" + age +
                ", classList=" + String.join(",",classList) +
                '}';
    }
}

1. 无参构造

<bean id="student" class="com.ecit.learn.ioc.xml.Student">
    <property name="name" value="y2m"/>
    <property name="age" value="23"/>
    <property name="classList">
        <list>
            <value>Java</value>
            <value>Web</value>
        </list>
    </property>
</bean>

2. 有参构造

<bean id="student" class="com.ecit.learn.ioc.xml.Student">
    <constructor-arg index="0" value="lisi"/>
    <constructor-arg index="1" value="12"/>
    <property name="classList">
        <list>
            <value>Java</value>
            <value>Web</value>
        </list>
    </property>
</bean>

3. 静态工厂方法

public class AnimalFactory {

    public static Animal getAnimal(String type){
        if ("Dog".equals(type)){
            return new Dog();
        }else {
            return new Cat();
        }
    }

}
<bean id="dog" class="com.ecit.learn.ioc.xml.AnimalFactory" factory-method="getAnimal">
    <constructor-arg value="Dog"/>
</bean>

<bean id="cat" class="com.ecit.learn.ioc.xml.AnimalFactory" factory-method="getAnimal">
    <constructor-arg value="Cat"/>
</bean>

4. 实例工厂方法

public class AnimalFactory {

    public Animal getAnimal(String type){
        if ("Dog".equals(type)){
            return new Dog();
        }else {
            return new Cat();
        }
    }

}
<bean name="animalFactory" class="com.ecit.learn.ioc.xml.AnimalFactory" />

<bean id="cat" factory-bean="animalFactory" factory-method="getAnimal">
    <constructor-arg value="Cat"/>
</bean>

注解配置方式

@Component声明

image.png

配置类中使用@Bean

@Configuration
public class BeanConfiguration {

    @Bean("dog")
    Animal getDog(){
        return new Dog();
    }
    
}

实现FactoryBean接口

@Component
public class MyCat implements FactoryBean<Animal> {

    @Override
    public Animal getObject() throws Exception {
        return new Cat();
    }

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

实现BeanDefinitionRegistryPostProcessor接口

@Component
public class MyBeanRegister implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        rootBeanDefinition.setBeanClass(Monkey.class);
        beanDefinitionRegistry.registerBeanDefinition("monkey",rootBeanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }

}

实现ImportBeanDefinitionRegistrar接口和使用@Import()

@Component
public class MyBeanImport implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        rootBeanDefinition.setBeanClass(Bird.class);
        registry.registerBeanDefinition("bird",rootBeanDefinition);
    }
}

image.png

优缺点比对

  • xml配置优点:低耦合、对象关系清晰、集中管理
  • xml配置缺点:配置繁琐、开发效率低、文件解析耗时
  • 注解优点:使用简单、开发效率高、高内聚
  • 注解缺点:配置分散、对象关系不清晰、配置修改需要重新编译整个工程