Spring基础篇-xml与Java配置两种属性注入(set方法与构造器注入的区别)!

不了解IoC中Bean注入的,可以先看看前一篇
Spring中Bean的注册

先创建一个类。

public class User {

    private Integer age;
    private String name;
    private String[] favorites;
    private Cat cat;
    private List<Dog> dogs;
    private Properties job;
    private Map info;
//省略get set 等方法
}

Set方法注入

 <bean class="com.tongzhou.demo.User" id="user">
        <property name="age" value="18"/>
        <property name="name" value="张三"/>
        <property name="cat" ref="cat01"/>
        <property name="dogs">
            <list>
                <ref bean="dog"/>
                <bean class="com.tongzhou.demo.Dog" >
                    <property name="name" value="小黑"/>
                </bean>
            </list>
        </property>
        <property name="favorites">
            <array>
                <value>足球</value>
                <value>篮球</value>
            </array>
        </property>
        <property name="job">
            <props>
                <prop key="salary">12000</prop>
                <prop key="position">工程师</prop>
            </props>
        </property>
    </bean>

这里通过反射赋值,本质上就是通过set方法进行赋值。

构造器注入

 <bean class="com.tongzhou.demo.User" id="user">
       <constructor-arg name="age" value="18"/>
        <constructor-arg name="cat" ref="cat"/>
        <constructor-arg name="dogs">
            <list>
                <ref bean="dog"/>
                <bean class="com.tongzhou.demo.Dog" id="dog2">
                    <property name="name" value="小蓝"/>
                </bean>
            </list>
        </constructor-arg>
        <constructor-arg name="favorites">
            <array>
                <value>篮球</value>
                <value>钢琴</value>
            </array>
        </constructor-arg>
        <constructor-arg name="info">
            <map>
                <entry key="address" value="广州"/>
            </map>
        </constructor-arg>
        <constructor-arg name="job">
            <props>
                <prop key="salary">12000</prop>
            </props>
        </constructor-arg>
        <constructor-arg name="name" value="张三"/>
    </bean>

自动注入

bean中autowire属性,默认是no,意思就是不进行自动注入
byName:分析当前bean的属性,去Spring容器中查找同名的属性。
byType:分析当前bean的类型,去Spring容器中查找同类型的属性。
constructor:寻找合适的构造方法,进行注入。
default:使用父标签的属性进行注入。

default案例

<beans default-autowire="byName">
    <bean class="com.tongzhou.demo.Cat" id="cat">
        <property name="name" value="小黄"/>
    </bean>

        <bean class="com.tongzhou.demo.Cat" id="cat2">
            <property name="name" value="小黑"/>
        </bean>
    <bean class="com.tongzhou.demo.User" id="user" autowire="default">
    </bean>
    </beans>
  ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring_autoware.xml");
  User bean = classPathXmlApplicationContext.getBean(User.class);
  System.out.println(bean);

这里可以看出来,通过byName,则名称相同的只有一个bean,所以只自动注入了第一个bean。

Java配置

public class JavaConfig {

    @Bean
    Person person(){
        Person person = new Person();
        person.setAge(18);
        person.setName("李四");
        return person;
    }
    }

注意,我这里暂时没有加@Configurable注解,这里是不影响的。

默认情况下,方法名就是bean名,bean中可重命名。

      AnnotationConfigApplicationContext javaConfig = new AnnotationConfigApplicationContext(JavaConfig.class);
        Person person = javaConfig.getBean("person", Person.class);
        System.out.println(person);

需要自定义名称,则可以在bean注解中进行改名。

@Bean("person")

那如果有多个类注入,并且需要相互依赖呢?
则可以通过如下的方式实现。

 @Bean("person")
    Person person(Dog dog){
        Person person = new Person();
        person.setAge(18);
        person.setName("李四");
        person.setDog(dog);
        return person;
    }

    @Bean
    Dog dog(){
        Dog dog = new Dog();
        dog.setName("小黑");
        return dog;
    }

调用

        AnnotationConfigApplicationContext javaConfig = new AnnotationConfigApplicationContext(JavaConfig.class);
        Person person = javaConfig.getBean("person", Person.class);
        Dog dog = javaConfig.getBean("dog", Dog.class);
        System.out.println(person.getDog() == dog);

结果,自然是true.

需要注意的是,Spring容器在加载的时候,会先在容器中寻找,依赖度bean有没有进行注册,如果有,则直接可以关联上,而如果通过再次实例化的方式,则获得的bean就不是同一个bean。

 @Bean("person")
    Person person(){
        Person person = new Person();
        person.setAge(18);
        person.setName("李四");
        Dog dog = new Dog();
        person.setDog(dog);
        return person;
    }

    @Bean
    Dog dog(){
        Dog dog = new Dog();
        dog.setName("小黑");
        return dog;
    }

调用

        AnnotationConfigApplicationContext javaConfig = new AnnotationConfigApplicationContext(JavaConfig.class);
        Person person = javaConfig.getBean("person", Person.class);
        Dog dog = javaConfig.getBean("dog", Dog.class);
        System.out.println(person.getDog() == dog);

结果自然是false.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值