Spring中的Bean管理
Spring中的Bean管理
Spring IOC容器
Spring框架主要是通过Spring容器实现的,Spring提供了相应的API来管理Bean,最常用的是BeanFactory和ApplicationContext
BeanFactory接口
这个接口采用Java的工厂模式,这个接口提供了创建和管理Bean的方法
方法名称 | 描述 |
---|---|
getBean(String name) | 根据参数名称获取Bean |
getBean(String name,Class <T>type) | 根据参数名称,参数类型来获取Bean |
<T>T getBean(Class<T>requiredType) | 根据参数类型获取Bean |
Object getBean(String name,Object…oegs) | 根据参数名称获取Bean |
isTypeMatch(String name,Resolvable Typetype) | 判断是否有与参数名称、参数类型匹配的Bean |
Class<T>getType(String name) | 根据参数名称获取类型 |
String[] getAliase(String name) | 根据实例的名称获取实例的别名数组 |
boolean containsBean(String name) | 根据Bean的名称判断Spring容器是否含有指定的Bean |
ApplicationContext接口
该接口建立在BeanFactory接口的基础之上,丰富了BeanFactory接口的特性,添加了对国际化,资源访问,事件传播等方面的支持
这个接口可以为单例的Bean实行预初始化,并根据< property >元素执行setter方法,单例Bean可以直接使用,提升了程序获取Bean实例的性能
类名称 | 描述 |
---|---|
ClassPathXmlApplicationContext | 从类路径加载配置文件,实例化ApplicationContext接口 |
FileSystemXmlApplicationContext | 从文件系统加载配置文件,实例化ApplicationContext接口 |
AnnotationConfigApplicationContext | 从注解中加载配置文件,实例化ApplicationContext接口 |
WebApplicationContext | 从Web应用中使用,从相对于Web根目录的路径中加载配置文件,实例化ApplicationContex接口 |
ConfigurableWebApplicationContext | 扩展了WebApplicationContext类,可以通过读取XML配置文件的方式实例化WebApplicationContext接口 |
Bean配置
在Spring中XML配置文件的根元素是< beans >,包含< bean >子元素,每个子元素可以定义一个Bean,通过< bean >元素将Bean注册到Spring容器中
- < bean >元素中的常用属性
- id 唯一标识符,Spring容器对Bean的配置和管理通过id属性完成,装配Bean时也需要根据id值获取对象
- name 可以为Bean指定多个名称
- class 只当Bean的具体实现类,其属性为对象所属类的全路径
- scope 设定Bean实例的作用范围
- < bean >元素常用的子元素
- < constructor-arg >可以为Bean的属性指定值,具有以下属性
- index:用于设置构造参数的序号
- type:用于指定构造参数类型
- ref:用于指定参数值
- value:用于指定参数值(参数值也可以通过ref和value的子元素指定)
- < property >是调用Bean实例中的setter方法完成属性赋值,从而完成依赖注入
- name:指定Bean实例中的属性名
- ref:用于指定参数值
- value:一样
- ref:是上面两个元素的属性,用于指定Bean工厂中某个Bean实例的引用
- value:用于指定一个常量值
- < list > 用于指定Bean属性类型为List或数组
- < set > 指定属性类型为Set
- < map >同上
- < entry > 该元素是< map >的子元素,用于设置一个键值对。< entry >元素的key属性用于指定字符串类型的键,用ref和value子元素指定< entry >元素的值,或者value-ref又或者value指定< entry > 元素的值
- < constructor-arg >可以为Bean的属性指定值,具有以下属性
Bean的实例化
构造方法的实例化
构造方法实例化是☞Spring容器通过Bean对应类中默认的无参构造方法来实例化Bean
在类中自定义无参构造方法,在applicationBean1.xml文件中配置一个id为bean1的Bean,通过class属性指定对应的实现类为Bean1,创建测试文件进行测试,测试成功便表明Spring容器成功调用Bean1类的默认构造方法完成了实例化
package com.yjw;
public class Bean1 {
public Bean1(){
System.out.println("这是Bean1");
}
}
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bean1" class="com.yjw.Bean1"></bean>
</beans>
静态工厂实例化
使用静态工厂实例化Bean时,还要定义一个静态工厂类,用静态工厂类中的方法创建Bean实例,此时的Bean配置文件class属性指定的不再是Bean的实现类,而是定义的静态工厂类;还要使用< bean > 元素的factory-method属性指定所定义的静态工厂方法
bean元素配置
通过factory-method属性指定静态工厂方法
<bean id="bean2" class="com.yjw.MyBean2Factory" factory-method="createBean"></bean>
创建MyBean2Factory类,定义静态方法用来创建Bean的实例
public class MyBean2Factory {
public static Bean2 createBean(){
return new Bean2();
}
}
实例工厂实例化
就是直接创建 Bean实例;在XML配置文件中,不使用class属性指向Bean所指向的类,而是使用factory-bean属性指向为Bean配置的实例工厂,并用factory-method属性指定要调用的实例工厂方法
package com.yjw;
public class MyBean3Factory {
public MyBean3Factory(){
System.out.println("工厂实例化中:");
}
public Bean3 createBean(){
return new Bean3();
}
}
<bean id="myBean3Factory" class="com.yjw.MyBean3Factory"></bean>
<bean id="bean3" factory-bean="myBean3Factory" factory-method="createBean"></bean>
createBean方法时非静态的,所以要创建工厂的实例才能调用,所以创建了两个Bean,一个是工厂,另一个是Bean3的实例
Bean的作用域
Sprinag容器创建一个Bean实例时,可以为该Bean指定作用域,也就是Bean实例的有效范围;使用scope属性来指定作用域
- singleton:单例模式。Spring容器只能存在一个共享的Bean实例,只要请求id或name与Bean的定义相匹配,就会返回Bean的同一个实例
- prototype:原型模式:每次从容器请求bean时,都会产生一个新的实例
- request:每个HTTP请求都会有一个Bean实例,该作用域只能基于Web的Spring ApplicationContext中使用
- session:每个HttpSession请求都会有自己的Bean实例,该作用域只能基于Web的Spring ApplicationContext中使用
- global session:限定一个Bean的作用域为Web应用(HttpSession)的声明周期,只有在Web中使用Spring时该作用域才有效
Bean的装配方式
也就是依赖的注入,分别有三种常见方式:基于XML装配,基于注解装配以及自动装配
基于XML的装配
也就是读取xml文件中的信息完成依赖注入,而基于XML的装配方式也有两种:setter方法注入和构造方法注入,之前笔记就有,我就不写了
基于注解装配
常用注解:
- @Component:指定一个普通的Bean,可以作用于任何层次
- @Controller:指定一个控制器组件Bean,将控制层的类标识为Spring中的Bean,功能上等同于@Component
- @Service:指定一个业务逻辑组件Bean,用于将业务逻辑层的类标识为Bean,功能上也等同于第一个
- @Repository:指定一个数据访问组件Bean,用于将数据访问层的类标识为Spring中的Bean功能上等同于第一个
- @Scope:指定Bean实例的作用域
- @Value:指定Bean实例的注入值
- @Autowired:指定要自动装配的对象
- @Resource:指定要注入的对象
- @Qualifier:指定要自动装配的对象名称,通常域@Autowired联合使用
- @PostConstruct:指定Bean实例完成初始化后调用的方法
- @PreDestroy:指定Bean实例销毁前的方法
具体步骤:
-
导入依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.2.8.RELEASE</version> </dependency>
-
创建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 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:component-scan base-package="com.yjw"/> </beans>
-
定义实体类
package com.yjw.entity; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component("user") @Scope("singleton") public class User { @Value("1") private int id; @Value("张三") private String name; @Value("123456") private String password; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String toString(){ return "id="+id+",name="+name+",password="+password; } }
-
定义DAO层
-
实现dao层
package com.yjw.dao; import com.yjw.entity.User; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Repository; //使用注解,将数据访问层标识为Spring中的Bean @Repository("userDao") public class UserDaoImpl implements UserDao { public void save(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = (User)applicationContext.getBean("user"); System.out.println(user); System.out.println("执行UserDaoImpl.save()"); } }
-
定义Service层
-
实现Service层
package com.yjw.service; import com.yjw.dao.UserDao; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service("userService") public class UserServiceImpl implements UserService{ //使用@Resource指定要注入的对象 @Resource(name = "userDao") private UserDao userDao; public void save(){ this.userDao.save(); System.out.println("执行UserServiceImpl.save()"); } }
-
定义Controller层
package com.yjw.controller; import com.yjw.service.UserService; import org.springframework.stereotype.Controller; import javax.annotation.Resource; @Controller public class UserController { //注入userService @Resource(name = "userService") private UserService userService; public void save(){ this.userService.save(); System.out.println("执行UserController.save()"); } }
-
定义测试类
package com.yjw; import com.yjw.controller.UserController; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AnnotationTest { public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserController userController =(UserController) applicationContext.getBean("userController"); userController.save(); } }
DAO(Data Access Object)数据访问层,负责与数据库进行交互,负责数据的增删改查操作
Service业务逻辑层:负责对业务逻辑进行处理,对数据进行加工和封装
Controller控制层:负责接收来自用于请求并调用相应的业务逻辑处理,将处理结果返回给用户
自动装配
Spring中的< bean >元素包含一个autowire属性,可以通过设置该属性实现Bean的自动装配
- default:有< bean >的上级元素的default-autowire属性值确定
- byName:根据bean元素id属性自动装配
- byType:根据bean元素的数据类型(Type)自动装配,如果一个Bean的数据类型兼容另一个Bean中的数据类型,则自动装配
- construct:根据构造函数的数据类型进行byType模式自动装配
- no:默认值,不使用自动装配,Bean依赖必须通过< ref >元素或ref属性定义
Bean的生命周期
Bean的生命周期指的时Bean实例被创建,初始化和销毁的过程。在Bean的两种作用域中,singleton和prototype中,前者Spring容器可以管理Bean的生命周期,控制Bean的创建初始化和销毁;在prototype作用域中,Spring容器只会创建实例,不会管理其生命周期
因此在Bean的生命周期中有两个节点非常重要,一个是Bean实例刚刚完成初始化,另一个时Bean实例被销毁之前,这两个时间点通常需要完成一些指定的操作;因此需要对这两个结点进行监控;可以使用注解来完成
@PostConstruct:指定Bean实例完成初始化后调用的方法,用于监控Bean对象初始化的节点
@PreDestroy:指定Bean实例销毁前的方法,用于监控Bean对象的销毁节点
监控时可以将这两个注解标注在特定的方法上
总结
-
了解Bean的配置以及,以及bean元素的常用属性以及子属性
-
了解Bean实例化的三种方法
- 使用构造方法进行Bean的实例化
- 创建工厂类,定义静态工厂方法,bean配置指向静态工厂类和静态工厂方法
- 创建工厂的Bean实例,在bean配置中在用相应属性指向工厂的Bean以及实例工厂方法
-
了解Bean的作用域
-
了解Bean的装配方式
- 基于XML装配:也就是setter方法注入以及构造方法注入
- 注解装配,了解相关注解的作用,用相关注解来注册Bean以及注入数值,并构建dao层,service层以及controller层
- 自动装配
-
Bean的生命周期
使用相关注解来监控Bean实例初始化以及被被销毁前的动作