定义Spring Bean
对应代码中的 BeanDefinition
,是 Spring Framework 中定义 Bean 的配置元信息接口,主要包含:
- Bean 的类名,全限定名称,具体实现类
- Bean 配置元信息:作用域、自动绑定(Auto Wiring)、生命周期回调……
- Bean 的引用:合作者(Collaborators)或者依赖(Dependencies),
- 配置的设置:Bean 的属性(比如连接池的大小)
BeanDefinition 元信息
概览
| 属性 | 说明 | 备注 | | —- | —- | —- | | Class | Bean 全类名,具体的类,不能是抽象类或接口 | | | Name | Bean 的名称或者 ID | | | Scope | Bean 的作用域(singleton、prototype、……) | | | Constructor arguments | Bean 构造器参数(用于依赖注入) | | | Properties | Bean 的属性设置(用于依赖注入) | | | Autowiring mode | Bean 自动绑定模式(比如:通过名称 byName……) | | | Lazy initialization mode | Bean 延迟初始化(延迟「需要时再初始化,缩短时间」、非延迟「默认」) | | | Initialization method | Bean 初始化回调方法名称 | | | Destruction method | Bean 销毁回调方法名称 | |
构建
通过 BeanDefinitionBuilder
// 1. 通过 BeanDefinitionBuilder 构建
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
// 通过属性设置(挨个添加),此处可以使用「beanDefinitionBuilder.addPropertyValue("name","Steve").addPropertyValue("id",30);」
beanDefinitionBuilder.addPropertyValue("name","Steve");
beanDefinitionBuilder.addPropertyValue("id",30);
// 获取 BeanDefinition 实例
BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
// beanDefinition 有好多 set 方法,BeanDefinition 并非 Bean 的终态,可以自定义修改
通过 AbstractBeanDefinition 以及派生类
// 2. 通过 AbstractBeanDefinition 以及派生类
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
// 设置 Bean 类型
genericBeanDefinition.setBeanClass(User.class);
// 通过 MutablePropertyValues 批量操作属性,此处可以使用 「propertyValues.add("name","Steve").add("id",31)」
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.addPropertyValue("name","Steve");
propertyValues.addPropertyValue("id",31);
genericBeanDefinition.setPropertyValues(propertyValues);
命名Spring Bean
Bean 名称
每个 Bean 都有一个或者多个标识符,标识符要在 Bean 的所在容器唯一。通常情况下,一个 Bean 有一个标识符,如果需要额外的标识符则使用别名扩充。
基于 XML 的情况下,可以用 id 或者 name 属性规定 Bean 的标识符。如果想使用别名,在 name 属性使用「,」或者「;」分开。
Bean 的 id 或者 name 可以留空,留空后,容器会为 Bean 自动生成唯一的名称。推荐使用驼峰,符合 Java 命名规范。
Spring 中可查看BeanNameGenerator
的两个实现。
注解实现
具体看:AnnotationBeanNameGenerator
比如用到的 @component
、@Repository
、@Service
、@Controller
等,其实后三者只是简单包了一层第一个
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
默认实现
具体看:DefaultBeanNameGenerator
Spring Bean 的别名
好处
- 可以复用现有的 BeanDefinitio
- 能够通过命名看出来使用场景(比如同一个 Bean 在 A 系统里叫 beanInA,在 B 系统里可以叫 beanInB)
注册 Spring Bean
基础
XML 配置元信息
Java 注解
Java API 配置元信息
- 命名方式:
BeanDefinitionRegistry#registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
- 非命名方式:
BeanDifinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefinition definition, BeanDefinitionRegistry registry)
- 配置类方式:
AnnotatedBeanDefinitionReader#register(Class<?>... componentClasses)
代码
```java import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;
/**
- 注解 BeanDefinition 示例 *
- @author mindartisan.blog.csdn.net
@date */ @Import(AnnotationBeanDefinitionDemo.Config.class)// 通过 @Import 进行导入 public class AnnotationBeanDefinitionDemo { public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 注册 配置类
// 方式 3:配置类方式;详细看:AnnotationConfigApplicationContext#register(Class<?>... componentClasses) -> AnnotatedBeanDefinitionReader#register(Class<?>... componentClasses)
applicationContext.register(AnnotationBeanDefinitionDemo.class);
registerUserBeanDefinition(applicationContext,"mindartisan-user");
registerUserBeanDefinition(applicationContext);
// 启动 Spring 应用上下文
applicationContext.refresh();
// 输出Config 类型的 Bean:{com.mindartisan.spring.geek.bean.definition.AnnotationBeanDefinitionDemo$Config=com.mindartisan.spring.geek.bean.definition.AnnotationBeanDefinitionDemo$Config@7f416310}
System.out.println("Config 类型的 Bean:" + applicationContext.getBeansOfType(Config.class));
// User 类型的 Bean:{user=User{id=1, name='Steve'}}
System.out.println("User 类型的 Bean:" + applicationContext.getBeansOfType(User.class));
// 关闭 Spring 应用上下文
applicationContext.close();
}
/**
* bean 的注册方式
*
* @param beanDefinitionRegistry
* @param beanName
*/
public static void registerUserBeanDefinition(BeanDefinitionRegistry beanDefinitionRegistry, String beanName) {
BeanDefinitionBuilder beanDefinitionBuilder = genericBeanDefinition(User.class);
beanDefinitionBuilder
.addPropertyValue("id", 1L)
.addPropertyValue("name", "Steve");
if (StringUtils.hasText(beanName)) {
// 命名方式注册 BeanDefinition
beanDefinitionRegistry.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
} else {
// 非命名方式
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinitionBuilder.getBeanDefinition(), beanDefinitionRegistry);
}
}
public static void registerUserBeanDefinition(BeanDefinitionRegistry beanDefinitionRegistry) {
registerUserBeanDefinition(beanDefinitionRegistry, null);
}
@Component// 通过 @Component 定义当前类作为 Spring Bean(组件)
public static class Config {
/**
* 通过 Java 注解,定义 Bean
*
* @return
*/
@Bean(name = {"user", "steve-user"})// 通过 @Bean,定义 Bean
public User user() {
User user = new User();
user.setId(1L);
user.setName("Steve");
return user;
}
}
}
<a name="UmRRd"></a>
## 扩展
通过外部单体对象注册,主要用到的是 `SingletonBeanRegistry#registerSingleton(String beanName, Object singletonObject);` 方法<br />SingtonBeanRegistrationDemo.class:
```java
/**
* 外部单体 Bean 注册实例
* 外部 bean:不被 Spring 管理的类
*
* @author mindartisan.blog.csdn.net
* @date
*/
public class SingtonBeanRegistrationDemo {
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 这里的 userFactory 未被 Spring 管理
UserFactory userFactory = new DefaultUserFactory();
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
// 启动 Spring 应用上下文
applicationContext.refresh();
// 注册外部单例对象
beanFactory.registerSingleton("userFactory", userFactory);
// 通过依赖查找的方式获取 userFactory
UserFactory userFactoryByLookup = beanFactory.getBean("userFactory", UserFactory.class);
System.out.println("userFactory == userFactoryByLookup:" + (userFactory == userFactoryByLookup));
// 关闭 Spring 应用上下文
applicationContext.close();
}
}
实例化 Spring Bean
常规
通过构造器(配置元信息:XML、Java 注解、Java API)
通过静态工厂方法(配置元信息:XML、Java API)
通过 Bean 工厂方法(配置元信息:XML、Java API)
通过 FactoryBean 方式(配置元信息:XML、Java 注解、Java API)
代码
具体方式看 xml 中注释,和 main 方法中的命名
User.class:
/**
* 用户
*
* @author mindartisan.blog.csdn.net
* @date
*/
public class User {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
/**
* 通过静态方法实例化
*
* @return {@link User}
*/
public static User createUser(){
User user = new User();
user.setId(1L);
user.setName("Steve");
return user;
}
}
bean-instantiation-context.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">
<!--静态方法实例化 Bean-->
<bean id="user-by-static-method" class="com.mindartisan.spring.geek.ioc.overview.domain.User"
factory-method="createUser"/>
<!--实例 Bean 方法实例化 bean-->
<bean id="user-by-instance-method" factory-bean="userFactory" factory-method="createUser"/>
<bean id="userFactory" class="com.mindartisan.spring.geek.bean.factory.DefaultUserFactory"/>
<!--FactoryBean 实例化 bean-->
<bean id="user-by-factory-bean" class="com.mindartisan.spring.geek.bean.factory.UserFactoryBean"/>
</beans>
BeanInstantinationDemo.class:
/**
* Bean 实例化 demo
*
* @author mindartisan.blog.csdn.net
* @date
*/
public class BeanInstantinationDemo {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("META-INF/bean-instantiation-context.xml");
User userByStaticMethod = beanFactory.getBean("user-by-static-method", User.class);
// 输出「User{id=1, name='Steve'}」
System.out.println(userByStaticMethod);
User userByInstanceMethod = beanFactory.getBean("user-by-instance-method", User.class);
// 输出「User{id=1, name='Steve'}」
System.out.println(userByInstanceMethod);
// 输出「false」
System.out.println(userByStaticMethod == userByInstanceMethod);
User userByFactoryBean = beanFactory.getBean("user-by-factory-bean", User.class);
// 输出「User{id=1, name='Steve'}」
System.out.println(userByFactoryBean);
// 输出「false」
System.out.println(userByStaticMethod == userByFactoryBean);
// 输出「false」
System.out.println(userByFactoryBean == userByInstanceMethod);
}
}
UserFactory.class:
/**
* 工厂类
*
* @author mindartisan.blog.csdn.net
* @date
*/
public interface UserFactory {
default User createUser(){
return User.createUser();
}
}
DefaultUserFactory.class:
/**
* 默认用户工厂
*
* @author mindartisan.blog.csdn.net
* @date
*/
public class DefaultUserFactory implements UserFactory {
}
UserFactoryBean.class:
/**
* 实现了 FactoryBean 的实现
*
* @author mindartisan.blog.csdn.net
* @date
*/
public class UserFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
return User.createUser();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}
特殊
通过 ServiceLoaderFactoryBean(配置元信息:XML、Java 注解、Java API)
通过 AutowireCapableBeanFactory#createBean(Java.lang.Class,int,boolean)
通过 BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)
代码
SpecialBeanInstantinationDemo.class:
/**
* 特殊的 Bean 实例化 demo
*
* @author mindartisan.blog.csdn.net
* @date
*/
public class SpecialBeanInstantinationDemo {
public static void main(String[] args) {
// serviceloader
BeanFactory beanFactory = new ClassPathXmlApplicationContext("META-INF/special-bean-instantiation-context.xml");
// 从 ServiceLoaderFactoryBean 中创建一个 ServiceLoader,再通过遍历的方式获取所有该 ServiceLoader 的实现类
// 在此代码中,创建一个「SecondUserFactory」的实现,displayServiceLoader 会输出两个「User{id=1, name='Steve'}」
ServiceLoader<UserFactory> userFactoryServiceLoader = beanFactory.getBean("userFactoryServiceLoader", ServiceLoader.class);
displayServiceLoader(userFactoryServiceLoader);
// demoServiceLoader();
System.out.println("---------------");
// 通过 applicationContext 获取 autowireCapableBeanFactory
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("META-INF/special-bean-instantiation-context.xml");
AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();
// 通过 autowireCapableBeanFactory 创建 userFactory 对象
// 注意:在 AutowireCapableBeanFactory#createBean(Class<T> beanClass) 的时候,beanClass 要具体的类,不能是接口或者抽象类
UserFactory userFactory = autowireCapableBeanFactory.createBean(DefaultUserFactory.class);
User user = userFactory.createUser();
// 输出「User{id=1, name='Steve'}」
System.out.println(user);
}
/**
* serviceloader demo
*/
public static void demoServiceLoader() {
ServiceLoader<UserFactory> userFactoryServiceLoader = ServiceLoader.load(UserFactory.class,
Thread.currentThread().getContextClassLoader());
displayServiceLoader(userFactoryServiceLoader);
}
public static void displayServiceLoader(ServiceLoader<UserFactory> userFactoryServiceLoader) {
Iterator<UserFactory> userFactoryIterator = userFactoryServiceLoader.iterator();
while (userFactoryIterator.hasNext()) {
UserFactory userFactory = userFactoryIterator.next();
// 输出「User{id=1, name='Steve'}」
System.out.println(userFactory.createUser());
}
}
}
special-bean-instantiation-context.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">
<bean id="userFactoryServiceLoader"
class="org.springframework.beans.factory.serviceloader.ServiceLoaderFactoryBean">
<property name="serviceType" value="com.mindartisan.spring.geek.bean.factory.UserFactory"/>
</bean>
</beans>
SecondUserFactory.class:
/**
* 次要用户工厂
*
* @author mindartisan.blog.csdn.net
* @date
*/
public class SecondUserFactory implements UserFactory {
}
META-INF/services/com.mindartisan.spring.geek.bean.factory.UserFactory
与 ServiceLoader 有关
com.mindartisan.spring.geek.bean.factory.DefaultUserFactory
com.mindartisan.spring.geek.bean.factory.SecondUserFactory
上述内容指定了com.mindartisan.spring.geek.bean.factory.UserFactory
的实现类
扩展:ServiceLoader
体现了 SPI 机制
JDK 的 ServiceLoader
在 main 方法中,使用了 JDK 自带的ServiceLoader
。上述的_META-INF/services/com.mindartisan.spring.geek.bean.factory.UserFactory_
之所以在 META/INF/services
这个路径下是因为 ServiceLoader
中下述代码:
private static final String PREFIX = "META-INF/services/";
Spring 中的 「ServiceLoader」
在 Spring 中,也提供了适配 JDK 中ServiceLoader
的实现:ServiceLoaderFactoryBean.class
,其父类AbstractServiceLoaderBasedFactoryBean.class
有三个子类,如下:
三个子类中对 AbstractServiceLoaderBasedFactoryBean#getObjectToExpose(ServiceLoader<?> serviceLoader)
有三种不同的实现:
- ServiceFactoryBean:返回一个
- ServiceLoaderFactoryBean:
- ServiceListFactoryBean:返回所有
在使用时,还要注意设置 serviceType
,xml 的配置方式如下:
<bean id="userFactoryServiceLoader" class="org.springframework.beans.factory.serviceloader.ServiceLoaderFactoryBean">
<property name="serviceType" value="com.mindartisan.spring.geek.bean.factory.UserFactory"/>
</bean>
初始化 Spring Bean
实现
- @PostConstruct 标注方法
- 实现 InitializingBean 接口的 afterPropertiesSet() 方法
自定义初始化方法
- XML 配置:
- Java 注解:@Bean(initMethod=”init”)
Java API:AbstractBeanDefinition#setInitMethodName(String)
代码
BeanInitializationDemo.class
@Configuration
public class BeanInitializationDemo {
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(BeanInitializationDemo.class);
// 启动 Spring 应用上下文
applicationContext.refresh();
UserFactory userFactory = applicationContext.getBean(UserFactory.class);
// 关闭 Spring 应用上下文
applicationContext.close();
}
@Bean(initMethod = "initUserFactory")
public UserFactory userFactory() {
return new DefaultUserFactory();
}
}
DefaultUserFactory.class ```java /**
- 默认用户工厂 *
- @author mindartisan.blog.csdn.net
@date */ public class DefaultUserFactory implements UserFactory, InitializingBean {
// Bean 初始化使用 // 1. 基于 @PostConstruct 注解 @PostConstruct public void init() { System.out.println(“@PostConstruct:UserFactory 初始化中”); }
- XML 配置:
public void initUserFactory() {
System.out.println("自定义初始化方法 initUserFactory():UserFactory 初始化中");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet:UserFactory 初始化中");
}
}
<a name="hPD77"></a>
## 顺序
参考:[Spring official](https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/spring-framework-reference/core.html#beans-factory-lifecycle-combined-effects)
1. 使用注解
1. 继承接口,重写方法
1. 手动配置的方法
<a name="d4d8269c"></a>
# 延迟初始化 Spring Bean
<a name="UkUhu"></a>
## 实现
1. XML 配置<bean lazy-init = "true" …/>
1. Java 注解:@Lazy
<a name="rNM6J"></a>
## 代码:
BeanInitializationDemo.class
```java
@Configuration
public class BeanInitializationDemo {
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(BeanInitializationDemo.class);
// 启动 Spring 应用上下文
applicationContext.refresh();
// 非延迟初始化在 Spring 应用上下文启动完成后被初始化
System.out.println("Spring 应用上下文已经启动");
UserFactory userFactory = applicationContext.getBean(UserFactory.class);
System.out.println("使用了 @Lazy 注解「当前为 true」:"+userFactory);
// 关闭 Spring 应用上下文
applicationContext.close();
}
@Bean(initMethod = "initUserFactory")
@Lazy(value = true)
public UserFactory userFactory() {
return new DefaultUserFactory();
}
}
当 @Lazy(value = true)
时,输出以下内容:
Spring 应用上下文已经启动 @PostConstruct:UserFactory 初始化中 afterPropertiesSet:UserFactory 初始化中 自定义初始化方法 initUserFactory():UserFactory 初始化中 使用了 @Lazy 注解「当前为 true」:com.mindartisan.spring.geek.bean.factory.DefaultUserFactory@197d671
BeanInitializationDemo.class
@Configuration
public class BeanInitializationDemo {
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(BeanInitializationDemo.class);
// 启动 Spring 应用上下文
applicationContext.refresh();
// 非延迟初始化在 Spring 应用上下文启动完成后被初始化
System.out.println("Spring 应用上下文已经启动");
UserFactory userFactory = applicationContext.getBean(UserFactory.class);
System.out.println("使用了 @Lazy 注解「当前为 false」:"+userFactory);
// 关闭 Spring 应用上下文
applicationContext.close();
}
@Bean(initMethod = "initUserFactory")
@Lazy(value = false)
public UserFactory userFactory() {
return new DefaultUserFactory();
}
}
当 @Lazy(value = fale)
时,输出以下内容:
@PostConstruct:UserFactory 初始化中 afterPropertiesSet:UserFactory 初始化中 自定义初始化方法 initUserFactory():UserFactory 初始化中 Spring 应用上下文已经启动 使用了 @Lazy 注解「当前为 false」:com.mindartisan.spring.geek.bean.factory.DefaultUserFactory@6b4a4e18
延迟初始化和非延迟初始化的主要区别是:延迟初始化在 Spring 应用上下文之后,非延迟在之前。
销毁Spring Bean
方式
@PreDestory
标注方法- 实现
DisposableBean#destory()
方法 自定义销毁方法
- XML 配置:
<bean destroy = "xxx" … />
- Java 注解:
@Bean(destroy = "xxx")
Java API:
AbstractBeanDefinition#setDestroyMethodName(String)
代码
BeanInitializationDemo.class
@Configuration
public class BeanInitializationDemo {
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(BeanInitializationDemo.class);
// 启动 Spring 应用上下文
applicationContext.refresh();
// 非延迟初始化在 Spring 应用上下文启动完成后被初始化
System.out.println("Spring 应用上下文已经启动");
UserFactory userFactory = applicationContext.getBean(UserFactory.class);
System.out.println("使用了 @Lazy 注解「当前为 false」:"+userFactory);
System.out.println("Spring 应用上下文准备关闭");
// 关闭 Spring 应用上下文
applicationContext.close();
System.out.println("Spring 应用上下文已经关闭");
}
@Bean(initMethod = "initUserFactory",destroyMethod = "doDestroy")
@Lazy(value = false)
public UserFactory userFactory() {
return new DefaultUserFactory();
}
}
DefaultUserFactory.class: ```java /**
- 默认用户工厂 *
- @author mindartisan.blog.csdn.net
@date */ public class DefaultUserFactory implements UserFactory, InitializingBean, DisposableBean {
// Bean 初始化使用 // 1. 基于 @PostConstruct 注解 @PostConstruct public void init() { System.out.println(“@PostConstruct:UserFactory 初始化中”); }
- XML 配置:
public void initUserFactory() {
System.out.println("自定义初始化方法 initUserFactory():UserFactory 初始化中");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet:UserFactory 初始化中");
}
@PreDestroy
public void preDestroy() {
System.out.println("@PreDestroy:UserFactory 销毁中");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean#destroy():UserFactory 销毁中");
}
/**
* 自定义销毁方法
*/
public void doDestroy() {
System.out.println("自定义销毁方法 doDestroy():UserFactory 销毁中");
}
}
``
当
@Lazy(value = fale)` 时,输出以下内容:
@PostConstruct:UserFactory 初始化中 afterPropertiesSet:UserFactory 初始化中 自定义初始化方法 initUserFactory():UserFactory 初始化中 Spring 应用上下文已经启动 使用了 @Lazy 注解「当前为 false」:com.mindartisan.spring.geek.bean.factory.DefaultUserFactory@197d671 Spring 应用上下文准备关闭 @PreDestroy:UserFactory 销毁中 DisposableBean#destroy():UserFactory 销毁中 自定义销毁方法 doDestroy():UserFactory 销毁中 Spring 应用上下文已经关闭
顺序
- 使用注解
- 继承接口,重写方法
-
源码分析
@PreDestory 标注方法
比较简单,直接 IDEA 搜
@PreDestory
的 usage: CommonAnnotationBeanPostProcessor.CommonAnnotationBeanPostProcessor();
- InitDestroyAnnotationBeanPostProcessor.setDestroyAnnotationType()
再在当前类下搜destroyAnnotationType
,会发现buildLifecycleMetadata()
方法中使用反射去找标注了注解的方法,有的话,就添加到销毁方法的集合中currDestroyMethods.add(new LifecycleElement(method));
实现 DisposableBean#destory()方法
首先看上文的输出,确定好是在 applicationContext.close()
将 Bean 销毁:
- AbstractApplicationContext.close();
- AbstractApplicationContext.doClose();
- AbstractApplicationContext.destroyBeans();
- ConfigurableBeanFactory.destroySingletons();
- DefaultListableBeanFactory.destroySingletons();
- DefaultSingletonBeanRegistry.destroySingletons();「这里通过遍历循环调用下一步」
- DefaultSingletonBeanRegistry.destroySingleton();
- DefaultSingletonBeanRegistry.destroyBean(String beanName, @Nullable DisposableBean bean);
- DisposableBean.destroy();
垃圾回收 Spring Bean
- 未理解,待办