@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的几种装配方式的区别
- autowired与构造函数执行的先后顺序**