Spring学习笔记
文章目录
1.0 Spring框架是什么?
Spring 是于 2003 年兴起的一个轻量级的 Java 开发框架,它是为了解决企业应用开发的复杂性而创建的**。Spring 的核心是控制反转(IOC)和面向切面编程(AOP)。**Spring 是可以在 Java SE/EE 中使用的轻量级开源框架。
Spring 的主要作用就是为代码“解耦”,降低代码间的耦合度。就是让对象和对象(模块和模块)之间关系不是使用代码关联,而是通过配置来说明。即在 Spring 中说明对象(模块)的关系。
Spring 根据代码的功能特点,使用 IOC 降低业务对象之间耦合度。IoC 使得主业务在相互调用过程中,不用再自己维护关系了,即不用再自己创建要使用的对象了。而是由 Spring 容器统一管理,自动“注入”,注入即赋值。 而 AOP 使得系统级服务得到了最大复用,且不用再由程序员手工将系统级服务“混杂”到主业务逻辑中了,而是由 Spring 容器统一完成“织入”。
1.2 Spring的优点
Spring 是一个框架,是一个半成品的软件。有 20 个模块组成。它是一个容器管理对象, 容器是装东西的,Spring 容器不装文本,数字。装的是对象。Spring 是存储对象的容器。
1.2.1 轻量
Spring 框架使用的 jar 都比较小,一般在 1M 以下或者几百 kb。Spring 核心功能的所需的 jar 总共在 3M 左右。Spring 框架运行占用的资源少,运行效率高。不依赖其他 jar。
1.2.2针对接口编程,解耦合
Spring 提供了 Ioc 控制反转,由容器管理对象,对象的依赖关系。原来在程序代码中的对象创建方式,现在由容器完成。对象之间的依赖解耦合。
1.2.3AOP 编程的支持
通过 Spring 提供的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付,在 Spring 中,开发人员可以从繁杂的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。
1.3 Spring体系结构
Spring 由 20 多个模块组成,它们可以分为数据访问/集成(Data Access/Integration)、Web、面向切面编程(AOP, Aspects)、提供JVM 的代理(Instrumentation)、消息发送(Messaging)、核心容器(Core Container)和测试(Test)。
1.4 IOC 控制反转
控制反转IoC(Inversion of Control) 是一个概念,是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理。控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。通过容器实现对象的创建,属性赋值, 依赖的管理。
IOC 是一个概念,是一种思想,其实现方式多种多样。当前比较流行的实现方式是依赖注入。应用广泛。
依赖:classA 类中含有 classB 的实例,在 classA 中调用 classB 的方法完成功能,即 classA对 classB 有依赖。
IOC 的实现:
依赖注入:DI(Dependency Injection),程序代码不做定位查询,这些工作由容器自行完成。
依赖注入 DI 是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。
-
Spring 的依赖注入对调用者与被调用者几乎没有任何要求,完全支持对象之间依赖关系的管理。Spring 框架使用依赖注入(DI)实现 IoC。
-
Spring 容器是一个超级大工厂,负责创建、管理所有的 Java 对象,这些 Java 对象被称为 Bean。Spring 容器管理着容器中 Bean 之间的依赖关系,Spring 使用“依赖注入”的方式来管理 Bean 之间的依赖关系。使用 IoC 实现对象之间的解耦和。
1.5 Spring的第一个程序
1.5.1新建一个maven工程
1.5.2补齐目录添加spring的依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- 添加spirng的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.19</version>
</dependency>
</dependencies>
1.5.3创建applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
:用于定义一个实例对象。一个实例对应一个 bean 元素。
id:该属性是 Bean 实例的唯一标识,程序通过 id 属性访问 Bean,Bean 与 Bean 间的依赖关系也是通过 id 属性关联的。
class:指定该 Bean 所属的类,注意这里只能是类,不能是接口。
<?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="stu" class="com.bbgu.edu.pojo.Student">
<property name="age" value="19"></property>
<property name="name" value="隔壁老王"></property>
</bean>
</beans>
添加测试类
- ApplicationContext 用于加载 Spring 的配置文件,在程序中充当“容器”的角色。其实现类有两个。
-
若 Spring 配置文件存放在项目的类路径下,则使用 ClassPathXmlApplicationContext 实现类进行加载。
-
ApplicationContext **容器,会在容器对象初始化时,将其中的所有对象一次性全部装配好。**以后代码中若要使用到这些对象,只需从内存中直接获取即可。执行效率较高。但占用内存。Spring初始化对象时要使用无参的构造方法,切记保证类中有无参构造方法。
-
使用 spring 容器创建的 java 对象。
1.6注入分类
bean 实例在调用无参构造器创建对象后,就要对 bean 对象的属性进行初始化。初始化是由容器自动完成的,称为注入。根据注入方式的不同,常用的有两类:set 注入、构造注入。
1.6.1set 注入
set 注入也叫设值注入是指,通过 setter 方法传入被调用者的实例。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。
引用类型
当指定 bean 的某属性值为另一 bean 的实例时,通过ref指定它们间的引用关系。ref 的值必须为某 bean 的 id 值。
Bean 对象的引用,使用标签的 ref 属性。
<!-- 学生信息-->
<bean id="stu" class="com.bbgu.edu.pojo.Student">
<property name="age" value="19"></property>
<property name="name" value="隔壁老王"></property>
</bean>
<!-- 学校信息-->
<bean id="ch" class="com.bbgu.edu.pojo.School">
<property name="schoolName" value="铁道大学"></property>
<property name="address" value="北京海淀"></property>
<property name="student" ref="stu"></property>
1.6.2构造方法注入
构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即,使用构造器设置依赖关系。在实体类中必须提供相应参数的构造方法。
标签中用于指定参数的属性有:
name:指定参数名称。
index:指明该参数对应着构造器的第几个参数,从 0 开始。不过,该属性不要也行, 但要注意,若参数类型相同,或之间有包含关系,则需要保证赋值顺序要与构造器中的参数顺序一致。
<!-- 学生信息-->
<bean id="stu" class="com.bbgu.edu.pojo.Student">
<constructor-arg index="0" value="张三"></constructor-arg>
<constructor-arg index="1" value="18"></constructor-arg>
</bean>
<!-- 学生信息-->
<bean id="stu" class="com.bbgu.edu.pojo.Student">
<constructor-arg name="name" value="张三"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
</bean>
必须提供相应的构造方法才可以
不指定名称和下标索引的注入
注意:此种方式的注入一定要按类中构造方法的参数的顺序来进行注入。
1.6.3byName与byType方式注入
1.7项目案例
使用三层架构完成用户数据的增加操作.由Spring容器负责对象的创建与依赖注入。
在分层开发中,Spring管理controller,service,dao各层的实现类对象的创建及依赖管理。
创建对象的思路分析:
1.7.1目录结构
controller
public class UserController {
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
//界成层的功能实现,对外提供访问的功能
public int insert(Users users){
return userService.insert(users);
}
}
UserMapper
public interface UserMapper {
// 添加一个学生
public int insert(Users users);
}
UserMapperImpl
public class UserMapperImpl implements UserMapper{
@Override
public int insert(Users users) {
System.out.println("用户增加成功!");
return 1;
}
}
UserService
public interface UserService {
//增加用户
public int insert(Users users);
}
UserServiceImpl
public class UserServiceImpl implements UserService {
private UserMapper userMapper;
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public int insert(Users users) {
return userMapper.insert(users);
}
}
applicationContext_Controller
<!--创建界面层的对象-->
<bean id="uController" class="com.bjpowernode.controller.UsersController">
<property name="usersService" ref="uService"></property>
</bean>
applicationContext_servince
<!--创建业务逻辑层的对象-->
<bean id="uService" class="com.bjpowernode.service.impl.UsersServiceImpl">
<property name="usersMappr" ref="uMapper"></property>
</bean>
applicationContext_mapper
<!--创建各种对象-->
<!--创建数据访问层的对象-->
<bean id="uMapper" class="com.bjpowernode.dao.UsersMapperImpl">
</bean>
total
<!--单个导入-->
<!--<import resource="applicatoinContext_mapper.xml"></import>-->
<!--<import resource="applicatoinContext_service.xml"></import>-->
<!--<import resource="applicatoinContext_controller.xml"></import>-->
<!--批量导入-->
<import resource="applicatoinContext_*.xml"></import>
1.8常用注解
1.8.1创建对象的注解
1.8.1.1@Component
创建所有对象都可以使用此注解,除了控制器,业务逻辑层,数据访问层的对象
1.8.1.2@Controller
创建控制器层的对象,此对象可以接收用户请求,返回处理结果
1.8.1.3@Service
创建业务逻辑层的对象,此对象可施事务控制,向上给控制器返回数据,向下调用数据访问层
1.8.1.4@Repository
创建数据访问层的对象 ,对数据库中的数据进行增删改查操作
1.8.2给对象赋值的注解
1.8.2.1@Value
给简单类型赋值
需要在属性上使用注解@Value,该注解的 value 属性用于指定要注入的值。
使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。
1.8.2.2@Autowired
给引用类型按类型注入
需要在引用属性上使用注解@Autowired,该注解默认使用按类型自动装配 Bean 的方式。使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加
到 setter 上。
@Autowired 还有一个属性 required,默认值为 true,表示当匹配失败后,会终止程序运行。若将其值设置为 false,则匹配失败,将被忽略,未匹配的属性值为 null。注意:如果可注入的类型多于一个,则按名称进行二次匹配.如果有匹配到则注入,如果没有匹配到,则报错。
1.8.2.3@Qualifier
给引用类型按名称注入
1.9基于注解三层架构的项目改造
在每个类上添加创建对象的注解@Controller,@Service,@Repository,每个需要依赖注入的成员变量使用按类型@Autowired依赖注入即可。
1.9.2拆分策略
常见的拆分策略有按模块拆分和按层拆分,当然在实际工作中,会有更细的拆分方法。
按模块拆分,例如用户模块applicationContext_user.xml,applicationContext_book.xml,每个xml文件中都包含相应的xxxController,xxxService,xxxDao的对象的创建。
按层拆分,例如拆分成applicationContext_controller.xml, applicationContext_service.xml,
applicationContext_dao.xml等,每个xml文件中有相关对象的创建,例如:applicationContext_controller.xml文件中包含userController,bookController等对象的创建。
1)单个文件导入
<import resource="applicatoinContext_mapper.xml"></import>
<import resource="applicatoinContext_service.xml"></import>
<import resource="applicatoinContext_controller.xml"></import>
2)批量导入
<import resource="applicatoinContext_*.xml"></import>
2.0 AOP 面向切面编程
AOP(Aspect Orient Programming),面向切面编程。面向切面编程是从动态角度考虑程序运行过程。AOP 底层,就是采用动态代理模式实现的。采用了两种代理:JDK 的动态代理,与 CGLIB的动态代理。
AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程,可通过运行期动态代理实现程序功能的统一维护的一种技术。AOP 是 Spring 框架中的一个重要内容。利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
面向切面编程,就是将交叉业务逻辑封装成切面,利用 AOP 容器的功能将切面织入到主业务逻辑中。所谓交叉业务逻辑是指,通用的、与主业务逻辑无关的代码,如安全检查、事务、日志、缓存等。若不使用 AOP,则会出现代码纠缠,即交叉业务逻辑与主业务逻辑混合在一起。这样, 会使主业务逻辑变的混杂不清。例如,转账,在真正转账业务逻辑前后,需要权限控制、日志记录、加载事务、结束事务等交叉业务逻辑,而这些业务逻辑与主业务逻辑间并无直接关系。但,它们的代码量所占比重能达到总代码量的一半甚至还多。它们的存在,不仅产生了大量的“冗余”代码,还大大干扰了主业务逻辑—转账。
2.1面向切面编程对有什么好处
1.减少重复。
2.专注业务。
注意:面向切面编程只是面向对象编程的一种补充。用 AOP 减少重复代码,专注业务实现。
2.2Spring支持AOP的编程,常用的有以下几种:
2.2.1Before通知
在目标方法被调用前调用,涉及接口org.springframework.aop.MethodBeforeAdvice
2.2.2After通知
在目标方法被调用后调用,涉及接口为org.springframework.aop.AfterReturningAdvice
2.2.3Throws通知
目标方法抛出异常时调用,涉及接口org.springframework.aop.ThrowsAdvice
2.2.4Around通知
拦截对目标对象方法调用,涉及接口为org.aopalliance.intercept.MethodInterceptor
2.3 AOP常用的术语
2.3.1切面
-
就是那些重复的,公共的,通用的功能称为切面,例如:日志,事务,权限。
-
切面泛指交叉业务逻辑,或是公共的,通用的业务。上例中的事务处理、日志处理就可以理解为切面。常用的切面是通知(Advice)。实际就是对主业务逻辑的一种增强。
2.3.2连接点
- 就是目标方法.因为在目标方法中要实现目标方法的功能和切面功能。
- 连接点指可以被切面织入的具体方法。通常业务接口中的方法均为连接点。
2.3.3切入点(Pointcut)
- 指定切入的位置,多个连接点构成切入点.切入点可以是一个目标方法,可以是一个类中的所有方法,可以是某个包下的所有类中的方法。
- 切入点指声明的一个或多个连接点的集合。通过切入点指定一组方法。被标记为 final 的方法是不能作为连接点与切入点的。因为最终的是不能被修改的,不能被增强的。
2.3.4目标对象
- 操作谁,谁就是目标对象。
- 目标对象指 将要被增强 的对象。 即包含主业 务逻辑的类的对象。
2.3.5通知(Advice)
- 来指定切入的时机.是在目标方法执行前还是执行后还是出错时,还是环绕目标方法切入切面功能。
- 通知表示切面的执行时间,Advice 也叫增强。
2.4 AspectJ简介
AspectJ 是一个优秀面向切面的框架,它扩展了 Java 语言,提供了强大的切面实现。
2.4.1AspectJ 中常用的通知有四种类型
(1)前置通知@Before
(2)后置通知@AfterReturning
(3)环绕通知@Around
(4)最终通知@After
(5)定义切入点@Pointcut(了解)
2.4.2 AspectJ 的切入点表达式
以上表达式共 4 个部分可简化如下:
execution(访问权限 方法返回值 方法声明(参数) 异常类型)
切入点表达式要匹配的对象就是目标方法的方法名。所以,execution 表达式中明显就是方法的签名。注意,表达式中黑色文字表示可省略部分,各部分间用空格分开。在其中可以使用以下符号:
2.4.3举例
execution(public * (…))
指定切入点为:任意公共方法。
execution( set(…))
指定切入点为:任何一个以“set”开始的方法。
execution( com.xyz.service.impl..(…))**
指定切入点为:定义在 service 包里的任意类的任意方法。
execution( com.xyz.service….(…)) * com.xyz.service.power2.aa..(…)*
指定切入点为:定义在 service 包或者子包里的任意类的任意方法。“…”出现在类名中时,后面必须跟“”,表示包、子包下的所有类。
execution( …service..(…)) a.b.service..(…) a.b.c.d.service..(…)
指定所有包下的 serivce 子包下所有类(接口)中所有方法为切入点
execution( .service..*(…))
指定只有一级包下的 serivce 子包下所有类(接口)中所有方法为切入点
execution(* .ISomeService.(…))
指定只有一级包下的 ISomeSerivce 接口中所有方法为切入点
execution(* …ISomeService.(…))
指定所有包下的 ISomeSerivce 接口中所有方法为切入点
execution(* com.xyz.service.IAccountService.(…))
指定切入点为:IAccountService 接口中的任意方法。
execution( com.xyz.service.IAccountService+.(…))
指定切入点为:IAccountService 若为接口,则为接口中的任意方法及其所有实现类中的任意方法;若为类,则为该类及其子类中的任意方法。
execution( joke(String,int)))
指定切入点为:所有的 joke(String,int)方法,且 joke()方法的第一个参数是 String,第二个参数是 int。如果方法中的参数类型是 java.lang 包下的类,可以直接使用类名,否则必须使用全限定类名,如 joke( java.util.List, int)。
execution(* joke(String,)))
指定切入点为:所有的 joke()方法,该方法第一个参数为 String,第二个参数可以是任意类型,如joke(String s1,String s2)和joke(String s1,double d2)都是,但joke(String s1,double d2,String
s3)不是。
execution( joke(String,…)))
指定切入点为:所有的 joke()方法,该方法第一个参数为 String,后面可以有任意个参数且参数类型不限,如 joke(String s1)、joke(String s1,String s2)和 joke(String s1,double d2,String s3) 都是。
execution(* joke(Object))
指定切入点为:所有的 joke()方法,方法拥有一个参数,且参数是 Object 类型。joke(Object ob)是,但,joke(String s)与 joke(User u)均不是。
execution(* joke(Object+)))
指定切入点为:所有的 joke()方法,方法拥有一个参数,且参数是 Object 类型或该类的子类。不仅 joke(Object ob)是,joke(String s)和 joke(User u)也是。
总结:
规范的公式:
execution(访问权限 方法返回值 方法声明(参数) 异常类型)
简化后的公式:
execution( 方法返回值 方法声明(参数) )
用到的符号:
- 代码任意个任意的字符(通配符)
… 如果出现在方法的参数中,则代表任意参数
如果出现在路径中,则代表本路径及其所有的子路径
2.5AspectJ 的开发环境
2.5.1引入依赖
2.5.2引入 AOP 约束
在 AspectJ 实现 AOP 时,要引入 AOP 的约束。配置文件中使用的 AOP 约束中的标签, 均是 AspectJ 框架使用的,而非 Spring 框架本身在实现 AOP 时使用的。
AspectJ 对于 AOP 的实现有注解和配置文件两种方式,常用是注解方式。
2.5.3AspectJ 基于注解的 AOP 实现
AspectJ 提供了以注解方式对于 AOP 的实现。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VQl6FXF6-1660548259475)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220815145059746.png)]
总结:
2.6SpringAOP与AspectJ的区别
2.7 Spring中事务的实现
Spring中事务的实现有两种方式,一种是基于xml文件的实现,一种是基于注解方式实现。在SSM的开发中,多使用注解方式实现事务的处理。
2.7.1基于xml方式的实现
添加依赖
<dependencies>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--aspectj依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--spring核心ioc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--做spring事务用到的-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!--mybatis和spring集成的依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!--阿里公司的数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
</dependencies>
<build>
<!--目的是把src/main/java目录中的xml文件包含到输出结果中。输出到classes目录中-->
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resourc
es</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
引入aop名称空间
引入tx名称空间
配置事务
<!--声明式事务的配置-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--使用xml方式声明事务-->
<!--配置切面的属性,哪些方法需要添加什么事务传播特性-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="select*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="search*" read-only="true"/>
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" no-rollback-for="ArithmeticException"/>
<tx:method name="insert*" propagation="REQUIRED" no-rollback-for="ArithmeticException"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="remove*" propagation="REQUIRED"/>
<tx:method name="clean*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="modify*" propagation="REQUIRED"/>
<tx:method name="set*" propagation="REQUIRED"/>
<tx:method name="change*" propagation="REQUIRED"/>
<tx:method name="*" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
<!--使用AOP的技术进行切入点织入-->
<aop:config >
<!--切入点表达式:指定在哪个包下的哪些类中的哪些方法添加事务处理-->
<aop:pointcut id="pointcat" expression="execution(* com.bjpowernode.service.*.*(..))"></aop:pointcut>
<!--完成切面与切入点绑定-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcat"></aop:advisor>
</aop:config>
2.7.2基于注解方式实现
导入相关依赖(同xml方式)
配置注解驱动
在对应的类上或方法上添加@Transactional设置传播特性
2.8 Spring的生命周期
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
1、Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法
2、Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
3、容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
4、工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器 接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。