Something about Bean的作用域:
^^Bean标签中有这样一个属性:scope,默认值是singleton,也就是单例模式,也就是说,在Spring容器中注册的Bean全局唯一,如果要修改成平常的可以new很多不同的对象的话,则要将scope的值显式修改为prototype
写在前头
^^之前我们在配置Bean的时候,我们会发现,有的Bean中嵌入了其它的自定义Bean(例如学生类Student中包含Address类),此时在手动装配时,我们需要在主类中显式地配置其它的依赖类(而这些依赖类之前早已在Spring容器中配置过了)。
^^那么,有没有一种偷懒的方法,可以不用主动地手工配置主类的依赖类呢?这时,自动装配应运而生。
1.在XML配置文件中实现自动装配
我们先来定义一个应用场景:一个人拥有猫和狗两只宠物。
接下来我们分别定义三个类:猫,狗,人
package com.yyl.pojo;
/**
* @Author: LongLongA
* @Description:
* @Date: Created in 15:47 2020/11/22
*/
public class Cat {
public void shout(){
System.out.println("miao~");
}
}
package com.yyl.pojo;
/**
* @Author: LongLongA
* @Description:
* @Date: Created in 15:47 2020/11/22
*/
public class Dog {
public void shout(){
System.out.println("wang!");
}
}
package com.yyl.pojo;
/**
* @Author: LongLongA
* @Description:
* @Date: Created in 15:47 2020/11/22
*/
public class People {
private String name;
private Cat cat;
private Dog dog;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", cat=" + cat +
", dog=" + dog +
'}';
}
}
然后,我们在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="com.yyl.pojo.Cat"/>
<bean id="dog" class="com.yyl.pojo.Dog"/>
<bean id="people" class="com.yyl.pojo.People">
<property name="name" value="LongLong"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
</bean>
</beans>
以上是常规配置方式,但显然,我们有时并不想在People类中再显示地配置一遍Cat,Dog的属性,如何使用自动装配呢?配置方式如下:
<?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="com.yyl.pojo.Cat"/>
<bean id="dog" class="com.yyl.pojo.Dog"/>
<!--
自动装配:autowire
byName查找的原理:
会自动在容器上下文中搜索和自己对象set方法后面的值对应的BeanId(例如setABC(),就找BeanId为abc的),此时需要保证Bean的Id值唯一
byType查找的原理:
会自动在容器上下文中搜索和自己待装配对象类型一致的Bean,但是必须保证该对象类型全局唯一
-->
<bean id="people" class="com.yyl.pojo.People" autowire="byName">
<property name="name" value="LongLong"/>
</bean>
</beans>
以上就是具体实现。
我们在bean标签中添加了autowire属性,主要可以使用byName或者byType两种值(默认是no,也就是关闭自动装配功能)
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
byName查找的原理:
会自动在容器上下文中搜索和自己待装配对象set方法后面的值对应的BeanId(例如setABC(),就找BeanId为abc的),此时需要保证Bean的Id值唯一
byType查找的原理:
会自动在容器上下文中搜索和自己待装配对象类型一致的Bean,但是必须保证该对象类型全局唯一
2.使用注解装配(重要)
除了上述在配置文件中实现自动装配的方式外,还可以通过注解的方式来实现。
【注】JDK1.5以后开始支持注解,Spring2.5开始就支持注解
在使用Spring的注解时需要以下步骤:
- 导入约束
- 声明注解配置: <context:annotation-config/>【千万憋整忘了嗷】
具体如下:
<?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/>
</beans>
实际应用
还是上面说到的猫,狗,人应用场景,此时,我们的配置文件更加简洁了:
<?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="cat" class="com.yyl.pojo.Cat"/>
<bean id="dog" class="com.yyl.pojo.Dog"/>
<bean id="people" class="com.yyl.pojo.People"/>
</beans>
与之前不同的是,需要在People类上做些文章:
我们可以看到,在People类中,将需要自动装配的依赖类(Cat,Dog)属性上设置了@Autowired注解,而且,当使用了@Autowired之后,类中的set方法就可以省略了,前提是该类在IOC容器中已经配置过了。
此外,@Autowired注解不仅可以在属性上使用,还可以在set方法上使用。
PS:
这里需要注意的是,自动装配的属性名最好要与配置文件中配置的Bean标签中的id属性值一致!!!
其实不一致也没关系,因为@Autowired原理是byType实现…
One more thing,千万不要忘记在XML配置文件中添加注解支持!!!
@Autowired的属性
另外,@Autowired标签有一个required属性,默认为true,但如果将其修改为false,那么该注解修饰的属性值可以为null,否则不允许为空
@Autowired(required = false)
private Dog dog;
@Autowired与@Qualifier
@Autowired标签时常与@Qualifier(value = “xxx”)连用,当一个IOC容器中配置了多个Dog类时,可以使用@Qualifier(value = “someIdName”)来指定你需要自动装配的类
@Autowired
@Qualifier(value = "dog2")
private Dog dog;
<bean id="dog" class="com.yyl.pojo.Dog"/>
<bean id="dog2" class="com.yyl.pojo.Dog"/>
@Resource注解
@Resource注解默认通过byName方法来实现,如果失败则再通过byType方式(即执行顺序:名字 ---->类型),当然,该注解也有一个属性值name,可以显式地赋值,内容对应为IOC容器定义的Bean类的id属性值。
@Resource(name = "dog2")
private Dog dog;
<bean id="dog" class="com.yyl.pojo.Dog"/>
<bean id="dog2" class="com.yyl.pojo.Dog"/>
@Resource可以理解为@Autowired与@Qualifier的集合体,前者不是spring框架中的注解,后者两个都是spring框架中的。