6.4 bean的作用域
作用域(bean scopes)
Scope | Description |
---|---|
singleton | (Default) Scopes a single bean definition to a single object instance for each Spring IoC container. |
prototype | Scopes a single bean definition to any number of object instances. |
request | Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext . |
session | Scopes a single bean definition to the lifecycle of an HTTP Session . Only valid in the context of a web-aware Spring ApplicationContext . |
application | Scopes a single bean definition to the lifecycle of a ServletContext . Only valid in the context of a web-aware Spring ApplicationContext . |
websocket | Scopes a single bean definition to the lifecycle of a WebSocket . Only valid in the context of a web-aware Spring ApplicationContext . |
6.4.1 单例模式(Spring默认机制),
==scope=“singleton”==一般单线程使用
<bean id="user2" class="com.yang.pojo.User" c:age="18" c:name="杨剑" scope="singleton"/>
6.4.2 原型模式
每次从容器中get的时候,都会产生一个新对象,多线程使用
<bean id="user2" class="com.yang.pojo.User" c:age="18" c:name="杨剑" scope="prototype"/>
6.4.3 其余的
其余的request,session,application,这些只能在web开发中用到
7.Bean的自动装配
- 自动装配是Spring满足bean依赖的一种方式
- Spring会在上下文中自动寻找,并自动给bean装配属性
==在Spring中有三种装配的方式
- 在xml中显示配置
- 在java中显示配置
- 隐式的自动装配bean**[重要]**
7.1测试
- 环境搭建
- 一个人有两个对象
7.2 ByName自动装配
byName:会自动在上下文中查找,和自己对象set方法后面的值对应的beanid!
<bean id="person" class="com.yang.pojo.Person" autowire="byName">
<property name="name" value="杨剑"/>
</bean>
7.3 ByType自动装配
byType:会自动在上下文中查找,和自己对象类型相同的beanid!
<bean id="person" class="com.yang.pojo.Person" autowire="byType">
<property name="name" value="杨剑"/>
</bean>
小结:
- byName的时候,需要保证所有的bean的id唯一,并且这个bean需要和自动注入的属性set方法的值一致
- byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!
7.4使用注解实现自动装配
jdk1.5支持的注解,Spring从2.5开始支持注解
使用注解须知:
-
导入约束。context约束
-
配置注解的支持
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=“http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd”>
3. ==开启注解的支持==
```xml
<context:annotation-config/>
@Autowired
-
直接在属性上使用,也可以在set方式上使用
-
使用**@Autowired** 我们可以不用编写set方法,前提是你这个自动装配的属性在IOC容器中存在且符合byName
-
科普
@Nullable 字段标记了这个注解,说明这个字段可以为null
public @interface Autowired { boolean required() default true; }
-
测试代码
public class Person { //如果显式的定义了Autowired的required属性为false,就说明这个对象可以为null,否则不可以为空 @Autowired(required = false) private Cat cat; @Autowired private Dog dog; private String name; }
-
如果**@Autowired** 自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用**@Qualifier(value = “xxx”)**配合使用,制定一个唯一的bean对象注入
package com.yang.pojo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; public class Person { //如果显式的定义了Autowired的required属性为false,就说明这个对象可以为null,否则不可以为空 @Autowired(required = false) private Cat cat; @Autowired @Qualifier(value = "dog222") private Dog dog; private String name; public Cat getCat() { return cat; } public Dog getDog() { return dog; } }
-
@Resource注解
public class Person { //如果显式的定义了Autowired的required属性为false,就说明这个对象可以为null,否则不可以为空 @Autowired(required = false) private Cat cat; @Resource @Qualifier(value = "dog222") private Dog dog; private String name; }
-
小结:@Resource和**@Autowired**的区别:
- 都用用来自动装配的 ,都可以放在属性字段上
- @Autowire通过byType的方式实现,而且必须要求对象存在
- @Resource默认按照byName的方式实现,如果找不到名字,则通过ByType实现!如果两个都找不到就报错
- 执行顺序不同。@Autowire:先type后name
- @Resource:先name后type
8.使用注解开发
在使用Spring4之后,要使用注解开发,必须要保证AOP的包导入
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yyxXCDie-1599882055270)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200912103257297.png)]
使用注解需要导入context约束,增加注解的支持
<?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>
8.1 bean
指定要扫描的包,这个包下的注解就会生效-
<context:component-scan base-package="com.yang.pojo"/>
@Component 组件
/*
等价与<bean id="user" class="com.yang.pojo.User"/>
@Component 组件
*/
@Component
public class User {
public String name = "杨剑";
}
8.2 属性如何注入
public class User {
/*
@Value("杨剑")
相当于
<bean id="user" class="com.yang.pojo.User">
<property name="name" value="杨剑"/>
</bean>
*/
@Value("杨剑")
public String name;
}
8.3 衍生的注解
@Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层
-
dao【@Repository】
-
service【@Service】
-
controller【@Controller】
这四个注解的功能都是一样的,都是代表将某个类注册到Spring中,装配Bean
8.4 自动装配注解
@Autowire
@Resource
@Nullable
@@Qualifier(value = "xxx")
8.5 作用域
@Scope("singleton")//单例模式
8.6 小结
xml与注解
- xml更加万能,适用于任何场合!维护简单方便
- 注解 不是自己的类使用不了,维护相对复杂
xml与注解的最佳实践:
-
xml用来管理bean,注解只负责属性的注入
-
我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解支持
<context:component-scan base-package="com.yang"/> <context:annotation-config/>
9.使用Java方式配置Spring
我们现在要完全不使用xml配置了
JavaConfig 是Spring的一个子项目,在Spring4之后成为了一个核心功能
实体类
package com.yang.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//这里这个注解的意思,就是说明这个类被Spring接管了,注册到了容器中
@Component
public class User {
private String name;
public String getName() {
return name;
}
@Value("杨剑")
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
配置文件
package com.yang.config;
import com.yang.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration//这个也会被Spring容器托管,注册到容器中,因为它本来就是一个@Component,@Configuration代表这是一个配置类,就和之前的beans.xml是一样的
@ComponentScan("com.yang")
@Import(YangConfig2.class)
public class YangConfig {
/*
注册一个bean就相当于我们之前写的一个bean标签
这个方法的名字就相当于bean标签中的id属性
返回值就相当于bean标签中的class属性
*/
@Bean
public User user() {
return new User();//就是要返回注入到bean的对象
}
}
测试类
import com.yang.config.YangConfig;
import com.yang.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
public static void main(String[] args) {
//如果完全使用了配置类去做,我们就只能通过AnnotationConfig上下文来获取容器,通过配置类的class对象加载
ApplicationContext context = new AnnotationConfigApplicationContext(YangConfig.class);
User getUser = context.getBean("user", User.class);
System.out.println(getUser.getName());
}
}
这种纯java的方式在SpringBoot中随处可见!