一我的有猫和狗两个宠物java
结构图:
Cat.javaweb
package pojo; public class Cat { public void shout() { System.out.println("喵~"); } }
Dog.javaspring
package pojo; public class Dog { public void shout() { System.out.println("汪~"); } }
People.javasvg
package pojo; public class People { private Cat cat; private Dog dog; private String name; public void setCat(Cat cat) { this.cat = cat; } public void setDog(Dog dog) { this.dog = dog; } public void setName(String name) { this.name = name; } public Cat getCat() { return cat; } public Dog getDog() { return dog; } public String getName() { return name; } }
beans.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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="cat" class="pojo.Cat"/> <bean id="dog" class="pojo.Dog"/> <bean id="people" class="pojo.People"> <property name="name" value="zsr"/> <property name="dog" ref="dog"/> <property name="cat" ref="cat"/> </bean> </beans>
MyTest.javaui
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import pojo.People; public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); People people = context.getBean("people", People.class); people.getDog().shout(); people.getCat().shout(); System.out.println(people.getName()); } }
测试:this
到此环境搭建成功!spa
上述代码中,ref
就是寻找对应的cat和dog对象;若是有一种机制,可以自动在bean里面寻找咱们要设置的cat或者dog,自动装配,就不用写下面的那两行代码了!这就引入了自动装配
指针
咱们更改一下.xml
文件,删除那两行代码,加入autowire
属性,发现有几种能够选择,这里先选择byName
code
<bean id="cat" class="pojo.Cat"/> <bean id="dog" class="pojo.Dog"/> <bean id="people" class="pojo.People" autowire="byName"> <property name="name" value="zsr"/> </bean>
再次运行测试类,依旧成功,说明咱们的cat和dog被自动设置到了people中
那咱们再更改一下,将dog
改成dog1
<bean id="cat" class="pojo.Cat"/> <bean id="dog1" class="pojo.Dog"/> <bean id="people" class="pojo.People" autowire="byName"> <property name="name" value="zsr"/> </bean>
再进行测试,发现空指针异常
为何??
byName
:根据属性名
自动装配,检查IoC容器并根据名字查找与属性彻底一致的bean,并将其与属性自动装配。
所以bean的id只有为dog
或者cat
才可以被找到
咱们再改一下,将byName
改成byType
<bean id="cat" class="pojo.Cat"/> <bean id="dog" class="pojo.Dog"/> <bean id="people" class="pojo.People" autowire="byType"> <property name="name" value="zsr"/> </bean>
再次运行,又成功了
byType
:根据属性类型
自动装配
必须保证类型全局惟一,若是多加一个dog,则报错:
能够省略id
<bean class="pojo.Cat"/> <bean class="pojo.Dog"/> <bean id="people" class="pojo.People" autowire="byType"> <property name="name" value="zsr"/> </bean>
小结
byName
的时候,须要保证全部bean的id惟一,而且这个bean id须要和实体类中对应的属性名相同byName
的时候,须要保证全部bean的class惟一,而且这个bean id须要和自动注入属性的类型一致;能够省略idjdk1.5支持注解,Spring2.5支持注解
要使用注解:
xml中导入约束
<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">
xml中配置注解支持
<context:annotation-config/>
set
方法set方法
上使用(适用于在set方法里面写一些处理逻辑的状况)<context:annotation-config/> <bean id="cat1" class="pojo.Cat"/> <bean id="dog1" class="pojo.Dog"/> <bean id="people" class="pojo.People"> <property name="name" value="zsr"/> </bean>
运行测试类,成功
自动装配环境很复杂的状况下:假设此时有两个cat和dog对象
<context:annotation-config/> <bean id="cat1" class="pojo.Cat"/> <bean id="cat2" class="pojo.Cat"/> <bean id="dog1" class="pojo.Dog"/> <bean id="dog2" class="pojo.Dog"/> <bean id="people" class="pojo.People"> <property name="name" value="zsr"/> </bean>
发现直接爆红了
这是由于没法匹配到对应的属性,@Autowired 默认经过 byType
的方式实现,若是有多个对象,则经过 byName
查找,若是都找不到,则报错;
此时经过有两个相同类型的对象,经过类型没法找到,bean id也不与属性名相同,经过名字也找不到,因此报错;
这时候就须要配合@Qualifier
来使用,指定惟一的bean对象来注入
再次运行,便可成功
@Qualifier
还能够设置required
属性值为false 容许属性值为null
咱们将上述的Autowired
换成Resource
xml文件为:
<context:annotation-config/> <bean id="cat1" class="pojo.Cat"/> <bean id="cat2" class="pojo.Cat"/> <bean id="dog1" class="pojo.Dog"/> <bean id="dog2" class="pojo.Dog"/> <bean id="people" class="pojo.People"> <property name="name" value="zsr"/> </bean>
直接运行
发现报错了,这是由于咱们没法匹配到对应的属性,@Resource 默认经过 byName
的方式实现,若是找不到名字, 则经过 byType
实现!若是两个都找不到,就会报错
此时,名字cat1/cat2/dog1/dog2
不匹配,且每一个类型的bean不惟一,因此经过名字和类型都找不到,所以报错
若是咱们将其中一个bean的id改成对应的属性名cat
和dog
<bean id="cat" class="pojo.Cat"/> <bean id="cat2" class="pojo.Cat"/> <bean id="dog" class="pojo.Dog"/> <bean id="dog2" class="pojo.Dog"/> <bean id="people" class="pojo.People"> <property name="name" value="zsr"/> </bean>
再次运行,成功了
这是由于咱们经过名字找到了
咱们还有另外一种解决方式,不用更改bean的id,咱们在@Resource
里面添加name
属性
经过设置name属性指定装配的对象
此时再运行,成功注入
@Autowired和@Resource的相同点:
属性字段
和set方法
上@Autowired和@Resource的区别:
byType
的方式实现,若是有多个对象,则经过 byName
查找,若是都找不到,则报错;此时能够用@Qualifier指定惟一的bean对象byName
的方式实现,若是找不到名字, 则经过 byType
实现!若是两个都找不到,就会报错