在Spring中将管理对象称为 Bean.Bean是由一个SpringIOC容器实例化,组装和管理的对象.也就是说,Bean并不是由我们程序员编写的,而是在程序运行过程中,由Spring通过反射机制生成的.
SpringBean是Spring框架在运行时管理的对象,我们编写的大多数逻辑代码都会存放在SpringBean中.
创建一个对象
提供依赖项(例如其他bean,配置属性)
拦截对象方法调用以及提供额外的框架功能
摧毁一个对象
基于XML文件的配置
使用注解
id: Bean的唯一标识符,Spring容器对Bean的配置,管理都通过该属性进行.
name:
Spring容器通过此属性进行配置和管理,name属性可以为Bean指定多个名称,每个名称之间使用逗号或者分号分开
class: 指定Bean的实现类,它必须使用类的全限定名
scope: 用于设定Bean示例的作用域,其属性值如下:
singleton: 单例的.即只创建一个对象,在Spring启动时就会创建好.
prototype: 原型的.每次都会创建一个对象,在获取时才会创建.
constructor-arg:
property:
name属性指定Bean实例中的相应属性名
ref属性及value属性用于指定参数值
ref:
value:
list: 用于封装List或数组属性的依赖注入
set: 用于封装Set类型属性的依赖注入
map: 用于封装Map类型的依赖注入
entry:
元素的子元素,用于设置一个键值对,其key属性指定字符串类型的键值.ref属性或value属性直接指定其值.也可以通过ref或者value子元素指定其值.
1.使用XML文件
使用xml文件进行SpringBean管理的方式很直观,但是较为麻烦我们在学习初期使用此种方式进行配置,在后期开发中建议使用注解的方式进行管理
代码实现:
注:
我们在使用
在使用
2.使用注解实现
在使用注解实现Bean管理之前,我们首先要进行配置,否则Spring无法帮我们找到对应的文件
Spring注解属性列表:
注解 | 说明 |
---|---|
@Component | 使用在类上,用于实例化Bean |
@Service | 使用在service层上,用于实例化Bean |
@Repository | 使用在dao层上,用于实例化Bean |
@Autowired | 使用在字段或setter上,用于根据类型依赖注入;使用在字段上就不需要再写setter |
@Qualifier | 结合@Autowired一起使用,用于根据名称进行依赖注入 |
@Resource | 相当于@Autowired+@Qualifier,按照名称进行依赖注入 |
@Value | 注入普通属性 |
@Scope | 标注Bean的作用范围 |
什么是依赖注入:
依赖注入,是IOC的一个方面,可以理解为不用我们自己创建对象,而是只需要描述它如何被创建,spring会帮我们创建,依赖外部的注入
使用注解前的配置:
1.导入注解所需的jar包: Spring的注解功能封装在aop包中,我们只需要导入Spring aop jar包即可,由于新版Spring jar包自动导入,此处我们无需再手动导入 2.在配置文件中开启扫描注解:
3.创建注解对象:
3.1 给实体类添加注解
@Component(value = "admin")
@Scope(value = "singleton")
public class Admin {
}
3.2 dao层
package com.ffyc.springdemo.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class AdminDao {
@Autowired
JdbcTemplate jdbcTemplate;
public void saveAdmin(){
System.out.println("保存管理员");
}
3.3 service层
package com.ffyc.springdemo.service;
import com.ffyc.springdemo.dao.AdminDao;
import com.ffyc.springdemo.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AdminService {
@Autowired
AdminDao adminDao;
public void saveAdmin(){
adminDao.saveAdmin();
}
}
测试类:
package com.ffyc.springdemo.test;
import com.ffyc.springdemo.service.AdminService;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
@Test
public void test() {
ApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");
AdminService adminService = app.getBean("adminService", AdminService.class);
adminService.saveAdmin();
}
}
操作结果:
我们可以看到使用注解的方式可以很轻松的替代原来需要在配置文件中进行的大量配置的功能.因此在后续的开发中我们也将使用注解的方式进行.但是使用注解也会有缺点,我们在下篇博客中进行分析.
Spring中所说的bean对象,与我们new的对象是不同的,Spring中所说的bean对象是指Spring框架所创建管理的我们的对象.
从宏观上来说,bean对象的实现可以分为5个阶段:
实例化实例化 Instantiation 通过反射机制以及工厂创建出来的原始对象
属性赋值 Populate
初始化 Initialization 完成对初始对象的各种赋值,完成后就把bean对象放入容器中
将 bean 对象放入到容器中,使用
销毁 Destruction
servlet对象是线程安全的吗?
不是,因为servlet对象只创建一个,多个请求访问的是同一个servlet对象,因此它不是线程安全的
Spring中的bean是否是线程安全的,需要看bean的作用于scope:
如果为Singleton表示是单例的,即不是线程安全的,会使用ThreadLocal为每个请求创建一个变量副本进行操作
如果为Prototype表示为原型额,是线程安全的,因为每到来一个请求就会为其创建一个bean.
有状态bean和无状态bean
有状态bean就是有数据存储功能,例如包含成员变量
无状态bean就是没有数据存储功能,例如service层和dao层,只是方法调用.