bean的作用域
翻译版

英文版

重点掌握单例和原型就可以了
单例模式(Spring 默认机制)
- 所有bean 共享一个实例化对象

xml
<bean id="user2" class="com.cike4.pojo.User" c:name="user2" c:age="20"
scope="singleton"/>
测试方法
java
@Test
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
// 这里申明了类型,就不需要强壮类型 User 类了
User user = context.getBean("user2", User.class);
User user2 = context.getBean("user2", User.class);
System.out.println(user==user2);
}
bean共享同一个实例化对象,所以返回true

原型模式
每次从容器中get的时候,都会产生一个新的对象

xml
<bean id="user2" class="com.cike4.pojo.User" c:name="user2" c:age="20" scope="prototype"/>
测试方法
java
@Test
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
// 这里申明了类型,就不需要强壮类型 User 类了
User user = context.getBean("user2", User.class);
User user2 = context.getBean("user2", User.class);
System.out.println(user.hashCode());
System.out.println(user2.hashCode());
System.out.println(user==user2);
}
两个获取的对象不相等,hash也不一样,因为实例化不一样

其余的
request、session、application、这些只能在web开发中使用
官方解释:
plain
https://docs.spring.io/spring-framework/docs/5.2.0.RELEASE/spring-framework-reference/core.html#beans-factory-scopes
https://docs.spring.io/spring-framework/reference/core/beans/factory-scopes.html
Bean的自动装配
- 自动装配是 Spring满足bean以来的一种方式!
- Spring会在上下文中国自动寻找,并自动给bean装配属性
在Spring中有三种装配的方式:
- 在XML中显示的配置
- 在Java中显示配置
- 隐式的自动装配bean 【重要的】
测试
环境搭建:一个人有两个宠物
byName自动装配
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应beanid
xml
<bean id="cat" class="com.cike5.pojo.Cat"/>
<bean id="dog" class="com.cike5.pojo.Dog"/>
<!--
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应beanid
-->
<bean class="com.cike5.pojo.People" id="people" autowire="byName">
<property name="name" value="cike_y"/>
</bean>

byType自动装配
- byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean
- 弊端,类型全局为一才会自动装配
xml
<bean class="com.cike5.pojo.Cat"/>
<bean class="com.cike5.pojo.Dog"/>
<!--
byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean
弊端,类型全局为一才会自动装配
-->
<bean class="com.cike5.pojo.People" id="people" autowire="byType">
<property name="name" value="cike_y"/>
</bean>
小结:
- byName的时候,需要保证所有bean的id唯一,并且bean需要和自动注入的属性set方法后面的字母一致!
- byTtype的时候,需要保证所有的bean的calss唯一,并且这个bean需要和自动注入的属性的类型一致!
官方解释:
plain
https://docs.spring.io/spring-framework/docs/5.2.0.RELEASE/spring-framework-reference/core.html#beans-autowired-annotation
https://docs.spring.io/spring-framework/reference/core/beans/annotation-config/autowired.html
使用注解实现自动装配
JDK1.5支持的注解,Spring2.5就支持注解了!
The introduction of annotation-based configuration raised the question of whether this approach is "better" than XML.
要使用注解须知:
- 导入约束。context约束
- 配置注解的支持
xml
<context:annotation-config/>
干净并且完整的xml配置:
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/>
</beans>
官方文档:
plain
https://docs.spring.io/spring-framework/docs/5.2.0.RELEASE/spring-framework-reference/core.html#beans-annotation-config
https://docs.spring.io/spring-framework/reference/core/beans/annotation-config.html
https://docs.spring.io/spring-framework/reference/core/beans/annotation-config/autowired.html
@Autowired
在类的属性上面进行注释
java
public class People {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
private String name;
public Cat getCat() {
return cat;
}
public Dog getDog() {
return dog;
}
}
- 不需要set方法了,因为是通过反射的原理实现的
- 使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在IoC(Spring)容器中存在且符合属性类型
测试方法
java
@Test
public void test(){
// 创建Spring容器对象
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
// 获取bean对象
People people = context.getBean("people", People.class);
people.getCat().shout();
people.getDog().shout();
}

科普
java
@Nullable 字段标记了这个注解,说明这个字段可以为null
可以这样子写,让name值为空
java
private @Nullable String name;

查看Autowired的注解接口,可以看见默认值是true
java
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
* <p>Defaults to {@code true}.
*/
boolean required() default true;
}
也可以这样子写
java
public class People {
// 如果显示定义了Autowired 的 required属性为false,说明这个对象可以为null,否则不允许为空
@Autowired (required = false)
private Cat cat;
@Autowired (required = false)
private Dog dog;
@Qualifier
可以进行显示定义进行自动装配
java
@Qualifier("dog11")
private Dog dog;
beans.xml 中的容器id为dog11,可以进行对应
java
<?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="dog11" class="com.cike5.pojo.Dog"/>
<bean id="cat" class="com.cike5.pojo.Cat"/>
<bean id="people" class="com.cike5.pojo.People"/>
</beans>
@Autowired和@Qualifier的区别:
- @Autowired是通过byType的方式实现的,而且这个对象必须存在
- @Qualifier则是通过byName的方式实现的,显式定义这个容器id
@Resource
支持隐式自动装配、也支持显示定义,相当于@Autowored和@Quailifier的结合体
java
public class People {
// 隐式定义、自动装配
@Resource
private Cat cat;
java
public class People {
// 显示定义指定容器id、自动装配
@Resource(name = "cat")
private Cat cat;
小结:
@Resource和 @Autowired的区别:
- 都是自动装配的,都可以放在属性字段上
- @Autowired通过byType的方式实现,而且必须要求这个对象必须存在【常用】
- @Resource 默认通过byName的方式实现,如果找不到,则会通过byType实现!如果两个都找不到的情况下,就会报错!最后也可以显示定义进行装配【常用】
- 执行的顺序不同:@Autowired通过byType的方式实现,Resource 默认通过byName的方式实现