@Autowired与xml.bean

@Autowired、setter、构造函数、beanxml-property、beanxml-constructor-arg 乱七八糟

一、写在前面

对于标题的这几个东西想必都不会陌生,但有的时候没有百分百的拿捏住具体的操作上的区别,虽然,有几个东西大家用的不多。本文只介绍用法区别。

二、用法介绍

(一)@Autowired

1、概念

(1)其实autowired它是用作装配(拿spring容器中的现成bean来使用,装配到当前的类bean中)。

(2)我觉得他是个局部的概念,用一个组件(组件也是个体)组装成另一个个体,若干个组件的组装在一起就构成了一个完整的个体。也是一个“过程”的概念。

(3)配置文件xml中的bean呢,跟Java的注解@Bean是一个意思。只是代码与xml的不同吧。他是一个独立的个体 + 这个个体如何去组装别人 或者 由别人组装。

autowired可以放在任意一个方法前,构造函数,域,Retention.RunTime意味着他的保持时间是运行时保留。

2、用法
(1)放在域前

public class Family {
	@Autowired
	private Student student;

}

这么写的意思是,在实例化Family这个类的一个对象时,会从spring容器中拿取一个类型为Student的bean塞到Family的student字段中。
在我看来autowired是一个拿的动作,或者叫使用。

其实把autowired放在域前 《==》 在xml中配置bean,使用setter注入。

(2)放在普通的方法前

@Component
public class ClassB {

    @Getter
    private ClassA classA;

    @Autowired
    private void obtainA(ClassA classA) {
        this.classA = classA;
    }
}

从上面代码可以看到,其实autowired可以放在任何一个普通的代码前,除了static,毕竟这个肯定是一个对象,而不是类。

(3)构造函数

@Component
public class ClassB {

    @Getter
    private ClassA classA;

    @Autowired
    public ClassB(ClassA classA) {
        this.classA = classA;
    }

(二)配置文件xml方式配置bean

1、概念

在配置文件里写bean什么的,很常用,与autowired的区别是,他定义一个个体(bean/类对象), 因此他也取代了@Component等注解的作用。bean的配置里面呢可以是各种组装(他们完成了autowired的工作)

(1) property 与 setter

//类B
public class ClassB {

    @Getter
    private ClassA classA;
}

//类A
public class ClassA {
    @Getter
    private String name = "jenny";
}

//配置文件
<bean id="classB" class="autowired.ClassB">
    <property name="classA" ref="classA"/>
</bean>

<bean id="classA" class="autowired.ClassA">
    <property name="name" value="jennyA"/>
</bean>

配置文件中,property的意思是会调用你当前类中相应域的setter方法来进行装配。如果你只是像上面这么写的话,会报错:

Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'name' of bean class [autowired.ClassA]: Bean property 'name' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

后来,你改为了:

public class ClassB {

    @Getter
    private ClassA classA;

    public void setClassA(ClassA classA) {
        this.classA = classA;
    }
}

public class ClassA {
    @Getter
    private String name = "jenny";

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

这样就没有问题了。

所以,从上面两段代码可以看出:bean.property + 相应字段的setter方法就可以完成 @Autowired + @Component的工作

(2)constructor-arg + 构造函数

//类B
public class ClassB {

    @Getter
    private ClassA classA;
	
    public ClassB (ClassA classA) {
        this.classA = classA;
    }
}

//类A
public class ClassA {
    @Getter
    private String name = "jenny";

    public ClassA(String name) {
        this.name = name;
    }

}

//配置文件
   <bean id="classA" class="autowired.ClassA">
        <constructor-arg name="name" value="jennyB"></constructor-arg>
    </bean>

    <bean id="classB" class="autowired.ClassB">
        <constructor-arg name="classA" ref="classA"></constructor-arg>
    </bean>

按照配置文件的写法,那么ClassA与ClassB中一定要有相应的构造函数才行,否则会报错。

所以,从上可以看出 constructor-arg 的方式可以等价于@Autowired注解。

这么说吧,有了@Autowired了,就取缔了property 和 constructor-arg,但是取缔不了bean元素,哈哈

(三)autowired与xml.bean的各种混用
随便写个例子吧


public class ClassB {

    @Getter
    private ClassA classA;

    @Autowired
    //或者放到域classA前也可以,方法前也可以
    public ClassB (ClassA classA) {
        this.classA = classA;
    }
}

<bean id="classA" class="autowired.ClassA">
    <constructor-arg name="name" value="jennyB"></constructor-arg>
</bean>

<bean id="classB" class="autowired.ClassB"></bean>

例子中,classB的xml.bean中并没有写如何装配classA,但是在java代码里写了进行自动装配,即从容器里找到这个类型的bean来装配,classA的bean则写在了xml文件里。

三、其他问题

1. autowired的几种装配方式的区别

2. autowired与构造函数执行的先后顺序

posted @ 2017-10-18 00:12  jennyjj  阅读(2066)  评论(0编辑  收藏  举报