Bean的作用域
单例模式
- 创建的实例只有一个,也就是通过相同的id获取bean对象获取的是同一个bean
- 使用scope="singleton"指定是单例模式, 而且在Spring中默认就是单例模式,
<!--使用p命名直接注入值, 相当于property, 但是在使用前必须加约束xmlns:p="http://www.springframework.org/schema/p"-->
<bean id="user1" class="User" p:name="Listen" p:age="20" scope="singleton"/>
public class Demo {
public static void main(String[] args) {
}
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContex.xml");
User user = (User)context.getBean("user1");
User user1 = context.getBean("user1", User.class);
System.out.println(user == user1);
System.out.println(user.toString());
System.out.println("================");
}
}
- 由结果看出是同一个bean对象
原型模式
- 使用原型模式就是使同一个id获取的bean对象是不一样的, 每次get都会产生新的对象
- 使用scope="prototype"指定是原型模式
<bean id="user" class="User" p:name="Listen" p:age="20" scope="prototype"/>
public class Demo {
public static void main(String[] args) {
}
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContex.xml");
User user = (User)context.getBean("user");
User user1 = context.getBean("user", User.class);
System.out.println(user == user1);
System.out.println(user.toString());
System.out.println("================");
}
}
- 由结果看出, 得到的不是同一个bean对象
其余三个作用域
- 其余request、session、application, 这些在web开发中使用, request就是一个bean对象在请求中一直活在, session就是在一个会话中一直活在, application就会全局一直活在
Bean的自动装配
- Bean的自动装配, spring满足bean依赖的一种方式, spring会在上下文中自动寻找, 并自动给bean进行装配, 在spring中有三种自动装配的方式
- 一: xml中显示的配置
- 二: 在java中显示配置
- 三: 隐式的自动装配bean(重点) : 就是使用byname的时候, 必须是注入的bean的id是唯一的, 使用bytype就是是注入的bean的class是唯一的
- byname的形式
用AutoWired的byName自动装配, 因为是使用byname所以需要注入的属性的名字和bean的id必须相同 , 也就是byname自动在上下文中进行查找, 和自己对象set方法后面的值所对应的beanId
<!-- 使用spring创建对象, 在spring中这些都称为bean -->
<bean id="cat1" class="model.Cat"/>
<bean id="cat" class="model.Cat"/>
<bean id="dog" class="model.Dog"/>
<bean id="people" class="model.People">
<property name="name" value="Listen"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
</bean>
<bean id="people1" class="model.People" autowire="byName">
<property name="name" value="Bike"/>
</bean>
- bytype的形式
使用AutoWired的bytype进行自动装配, 使用bytype的时候, 会自动在上下文中寻找, 和自己对象属性类型相匹配的beanId, 也就是名字可以不一样, 但是这个相匹配类型的beanId只能是一个, 如果有多个就会出错, 还有一点就是使用bytype的时候, 类型相匹配的那个beanId是可以省略的
<bean id="cat" class="model.Cat"/>
<bean id="dog" class="model.Dog"/>
<bean id="people" class="model.People">
<property name="name" value="Listen"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
</bean>
<bean id="people2" class="model.People" autowire="byType">
<property name="name" value="Flake"/>
</bean>
注解装配
- 使用注解实现自动装配: @AutoWired和@Resource
public class People {
@Autowired
private Dog dog;
@Resource
private Cat cat;
private String name;
- 在使用前必须
- 导入约束xmlns:context=“http://www.springframework.org/schema/context”
完整就是
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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd”>
- 配置注解的支持,
<context:annotation-config/>
注意使用@AutoWired给对象自动加注入的时候, 还要保证属性名字和IOC中已经存在的bean的名字要相同 ,这个注解可以加在属性上, 也可以加在set方法上, 当然你加到属性上的时候set方法可以省略
<bean id="people3" class="model.People">
<property name="name" value="Mink"/>
</bean>
- 给类中字段加上注解之后就可以按上述这样写, 就会帮我们完成字段的装配, 当然类中的注解也可以使用@Resource, 但是又有不同点
- 额外注解知识给属性字段加了@Nullable意思就是这个字段可以为空, 也就是即使我们不为他注入依赖, 当我们访问的时候也不会报错
public void setName(@Nullable String name) {
this.name = name;
}
- 在使用@AutoWired(required=false) 就表示这个属性可以为空, 不会报错, 默认是true不容许为null的
- @Qualifier(value=“XXX”) 可以指定自动装配的是哪个bean, 使用@AutoWired的时候, 被注入的那个bean的type是唯一才可以, 如果是多个的时候, 我们就可以使用这个指定那个bean注入, 所以这个注解是配套@AutoWired去使用的
- 使用java原生的注解去自动装配@Resource, 这个字段装配是先判断name唯一匹配, 如果找不到再去使用type唯一匹配, 这个注解也可以指定加@Resource(name=“XXX”) 去指定一个bean去装配, 使用这个功能强大一点, 但是效率略低
@AutoWired和@Resource的区别
- 相同点就是: 都是用来自动装配的, 都可以放在属性字段上,
- 不同点:
@AutoWired通过bytype的方式实现, 找不到就报错, 也可以通过@Quailfire(value指定name去找, 是spring自带的装配方式
@Resource是默认找byname的方式, 但是找不到还会使用bytype的方式去找,俩种方式都找不到了才会报错, 如果需要找到指定bean的时候, Resource直接加(name 指定就行
@Autowired
@Qualifier(value = "dog1")
private Dog dog;
@Resource(name = "cat1")
private Cat cat;