bean自动装配
原生的自动装配
三个实体类分别是Dog、Cat和Person 我这里偷懒了,是用来lombok插件,来生成get、set和toString方法
首先创建三个实体类分别是dog、cat、person
package com.zkw.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter @Getter @ToString
public class Dog {
private String dog;
public void shout(){
System.out.println(dog+":"+"汪汪汪~~~");
}
}
package com.zkw.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter @Getter @ToString
public class Cat {
private String cat;
public void shout(){
System.out.println(cat+":"+"喵喵喵~~~");
}
}
package com.zkw.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter @Getter @ToString
public class Person {
private Cat cat;
private Dog dog;
private String name;
}
测试类MyTest.java
,我这里使用了junit这个工具类来进行测试了,也可以采用main方法来测试
import com.zkw.pojo.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void TestOne(){
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
Person person = context.getBean("person", Person.class);
System.out.println(person.toString());
person.getCat().shout();
person.getDog().shout();
}
}
最初的手动装配的ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat" class="com.zkw.pojo.Cat">
<property name="cat" value="肥波"/>
</bean>
<bean id="dog" class="com.zkw.pojo.Dog">
<property name="dog" value="哈士奇"/>
</bean>
<bean id="person" class="com.zkw.pojo.Person">
<property name="name" value="CRAZY"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
</bean>
</beans>
自动装配bean,其实就是修改ApplicationContext.xml
这个文件,自动装配的关键字为autowire="装配的方法"
,最常用的装配方法有两种分别是**byName
和byType
**
byName的使用
<bean id="cat" class="com.zkw.pojo.Cat">
<property name="cat" value="肥波"/>
</bean>
<bean id="dog" class="com.zkw.pojo.Dog">
<property name="dog" value="哈士奇"/>
</bean>
<bean id="person" class="com.zkw.pojo.Person" autowire="byName">
<property name="name" value="CRAZY"/>
</bean>
byName:会在容器的上下文寻找,和自己对象里边set方法后边对应的bean id。
**解释:在Person.java
这个类里边存在一个pubic void setCat
和pubilc void SetDog
这个两个方法,当注入的时候,它在Person.java
中先拿到了SetCat
和SetDog
中的Cat
和Dog
之后再来看 bean 中是否有 id 等于这两个,如果有就直接把它装配进去。 **
注意:因为
byName
自动装配的特殊要求,它需要保证bean中的id全局唯一,并且要求bean需要和自动注入的属性和set方法中的值一致这里的属性指的是SetDog中的dog
byType的使用
<bean class="com.zkw.pojo.Cat">
<property name="cat" value="肥波"/>
</bean>
<bean class="com.zkw.pojo.Dog">
<property name="dog" value="哈士奇"/>
</bean>
<bean id="person" class="com.zkw.pojo.Person" autowire="byName">
<property name="name" value="CRAZY"/>
</bean>
byType:会自动在容器上下文查找,和自己对象属性类型相同的 bean
所以这时候bean的id就可要可不要了
注意:在使用byType的时候,需要保证bean的class唯一,并且这个bean需要和自动注入的属性的类型一致。
结果如图所示
注解实现的自动装配
使用注解开发的时候,ApplicationContext.xml和Person.java会发生一些微小的变化
ApplicationContext.xml
文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解-->
<context:annotation-config/>
<bean id="cat12" class="com.zkw.pojo.Cat"> <property name="cat" value="肥波12"/> </bean>
<bean id="cat" class="com.zkw.pojo.Cat"> <property name="cat" value="肥波"/> </bean>
<bean id="cat2" class="com.zkw.pojo.Cat"> <property name="cat" value="肥波2"/> </bean>
<bean id="dog" class="com.zkw.pojo.Dog"> <property name="dog" value="哈士奇"/> </bean>
<bean id="person" class="com.zkw.pojo.Person"> <property name="name" value="CRAZY"/> </bean>
</beans>
@Autowired
Person.java
package com.zkw.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@Getter @Setter @ToString
public class Person {
@Autowired
@Qualifier(value = "cat12")
private Cat cat;
@Autowired
private Dog dog;
private String name;
}
@Autowired: 自动装配通过 类型(byType)、名字(byName) 如果@Autowired都不能唯一的装配,就需要使用 @Qualifier(value = “xxx”)来进行装配。 @Autowired 可以作用在属性上,也可以作用在set方法上,甚至换可以把set方法给删除了,只留一个get方法。
结果如图所示:
@Autowired(required=false)
@Autowired(required=true):默认下都是required=true可不用写,表示不能忽略当前要注入的bean,如果有直接注入,没有直接报错。
@Autowired(required=false):表示忽略当前要注入的bean,如果有直接注入,没有跳过,不会报错。
测试:
结果如图所示:
@Resources
Person.java
package com.zkw.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.annotation.Resource;
@Getter @Setter @ToString
public class Person {
@Resource(name = "cat2",type = Cat.class)
private Cat cat;
@Resource
private Dog dog;
private String name;
}
@Resources注解,它可以设置 byName 和byType来进行自动装配。
- 当设置了 name和type 即:@Resource(name = “xxx”, type = xxx.class),根据设置的条件到ioc中注入唯一的 对象
- 当只设置了name,则按照name,装配,如果没有那么抛出异常。
- 当只设置了type,那么按照类型装配,如果ioc容器当中存在多个,或不存在,抛出异常。
- 如果name和type都没有指定,那么先按byName查找,(如果 @Autowire注解标注在对象上 byName查找的值 是对象的字段名,在方法上,则是参数的名), 如果byName 没查找到,那么就进行 byType查找。如果都没查找到,那么抛出异常。
结果如图所示: