作者简介:zhz小白
公众号:小白的Java进阶之路
专业技能:
1、Java基础,并精通多线程的开发,熟悉JVM原理
2、熟悉Java基础,并精通多线程的开发,熟悉JVM原理,具备⼀定的线上调优经验
3、熟悉MySQL数据库调优,索引原理等,⽇志原理等,并且有出过⼀篇专栏
4、了解计算机⽹络,对TCP协议,滑动窗⼝原理等有⼀定了解
5、熟悉Spring,Spring MVC,Mybatis,阅读过部分Spring源码
6、熟悉SpringCloud Alibaba体系,阅读过Nacos,Sentinel,Seata,Dubbo,Feign,Gateway核⼼源码与设计,⼆次开发能⼒
7、熟悉消息队列(Kafka,RocketMQ)的原理与设计
8、熟悉分库分表ShardingSphere,具有真实⽣产的数据迁移经验
9、熟悉分布式缓存中间件Redis,对其的核⼼数据结构,部署架构,⾼并发问题解决⽅案有⼀定的积累
10、熟悉常⽤设计模式,并运⽤于实践⼯作中
11、了解ElasticSearch,对其核⼼的原理有⼀定的了解
12、了解K8s,Jekins,GitLab
13、了解VUE,GO
14、⽬前有正在利⽤闲暇时间做互游游戏,开发、运维、运营、推销等
本人著作git项目:https://gitee.com/zhouzhz/star-jersey-platform,有兴趣的可以私聊博主一起编写,或者给颗star
领域:对支付(FMS,FUND,PAY),订单(OMS),出行行业等有相关的开发领域
如果此文还不错的话,还请关注、点赞、收藏三连支持一下博主~
对于一个SpringBean来说,他会整体经过以下流程,才会创建一个完整的Bean
简略为:
我们这次主要是针对SpringBean的最后两步讲解,就是Bean的初始化,和销毁。
具体怎么操作,我们只需要对
package com.zhz.bean;
import lombok.*;
/**
* @author zhouhengzhe
* @description: 实体类
* @date 2022/11/4 10:12
* @since v1
*/
@Data
@AllArgsConstructor
@Builder
public class Person {
private String name;
private Integer age;
public void init() {
System.out.println("Person初始化完成");
}
public void destroy() {
System.out.println("Person销毁成功");
}
public Person() {
System.out.println("初始化构造方法");
}
}
package com.zhz.config;
import com.zhz.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 生命周期相关配置
* @author zhouhengzhe
* @date 2022/11/21
*/
@Configuration
public class MainConfigByLifeCycle {
@Bean(initMethod = "init",destroyMethod = "destroy")
public Person person(){
return new Person();
}
}
@Test
public void test4ByLiseCycle(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigByLifeCycle.class);
System.out.println("容器创建完成");
applicationContext.close();
}
我们可以发现,Spring的Bean在单例的时候,他会按顺序执行
package com.zhz.bean;
import lombok.*;
/**
* @author zhouhengzhe
* @description: 实体类
* @date 2022/11/4 10:12
* @since v1
*/
@Data
@AllArgsConstructor
@Builder
public class Person {
private String name;
private Integer age;
public void init() {
System.out.println("Person初始化完成");
}
public void destroy() {
System.out.println("Person销毁成功");
}
public Person() {
System.out.println("初始化构造方法");
}
}
package com.zhz.config;
import com.zhz.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 生命周期相关配置
* @author zhouhengzhe
* @date 2022/11/21
*/
@Configuration
public class MainConfigByLifeCycle {
@Scope("prototype")
@Bean(initMethod = "init",destroyMethod = "destroy")
public Person person(){
return new Person();
}
}
@Test
public void test4ByLiseCycle(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigByLifeCycle.class);
System.out.println("容器创建完成");
applicationContext.close();
}
我们可以发现在类没有去调用的话,就不会有类的构造方法,初始化的引用。
然后我们再看一下,创建类的时候,代码如下:
@Test
public void test4ByLiseCycle(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigByLifeCycle.class);
System.out.println("容器创建完成");
Person bean = applicationContext.getBean(Person.class);
applicationContext.close();
}
我们可以发现Spring的Bean在多例的情况下,Spring容器不会管理这个bean,也就不会自动调用这个bean的销毁方法。
其主要源码如下:
/*
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory;
/**
* Interface to be implemented by beans that need to react once all their properties
* have been set by a {@link BeanFactory}: e.g. to perform custom initialization,
* or merely to check that all mandatory properties have been set.
*
* An alternative to implementing {@code InitializingBean} is specifying a custom
* init method, for example in an XML bean definition. For a list of all bean
* lifecycle methods, see the {@link BeanFactory BeanFactory javadocs}.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see DisposableBean
* @see org.springframework.beans.factory.config.BeanDefinition#getPropertyValues()
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#getInitMethodName()
*/
public interface InitializingBean {
/**
* Invoked by the containing {@code BeanFactory} after it has set all bean properties
* and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
* This method allows the bean instance to perform validation of its overall
* configuration and final initialization when all bean properties have been set.
* @throws Exception in the event of misconfiguration (such as failure to set an
* essential property) or if initialization fails for any other reason
* 用于属性赋值之后调用。
*/
void afterPropertiesSet() throws Exception;
}
在上面源码中,afterPropertiesSet()方法是在属性赋值之后调用的,那么他究竟是在哪调用的呢?我们直接看源码,我们直接全局搜索,可以发现他是这个以下这份代码初始化的。大家有兴趣的可以直接搜一下方法。我这里给大家往前推一下代码:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
他的上层方法调用是以下方法:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
再往上推一步就是org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean这个方法,大家有兴趣可以看一下。
实现org.springframework.beans.factory.DisposableBean接口会再bean销毁前,spring才会调用org.springframework.beans.factory.DisposableBean#destroy方法。
我们先看其源码,代码如下:
/*
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory;
/**
* Interface to be implemented by beans that want to release resources on destruction.
* A {@link BeanFactory} will invoke the destroy method on individual destruction of a
* scoped bean. An {@link org.springframework.context.ApplicationContext} is supposed
* to dispose all of its singletons on shutdown, driven by the application lifecycle.
*
* A Spring-managed bean may also implement Java's {@link AutoCloseable} interface
* for the same purpose. An alternative to implementing an interface is specifying a
* custom destroy method, for example in an XML bean definition. For a list of all
* bean lifecycle methods, see the {@link BeanFactory BeanFactory javadocs}.
*
* @author Juergen Hoeller
* @since 12.08.2003
* @see InitializingBean
* @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName()
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons()
* @see org.springframework.context.ConfigurableApplicationContext#close()
*/
public interface DisposableBean {
/**
* Invoked by the containing {@code BeanFactory} on destruction of a bean.
* @throws Exception in case of shutdown errors. Exceptions will get logged
* but not rethrown to allow other beans to release their resources as well.
*/
void destroy() throws Exception;
}
首先我们创建一个对象,他实现了InitializingBean和DisposableBean,代码如下:
package com.zhz.bean;
import lombok.*;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/**
* @author zhouhengzhe
* @description: 实体类
* @date 2022/11/4 10:12
* @since v1
*/
@Data
@AllArgsConstructor
@Builder
public class Person implements InitializingBean, DisposableBean {
private String name;
private Integer age;
public Person() {
System.out.println("初始化构造方法");
}
/**
* 会在bean创建完成,并且属性都赋好值以后进行调用
*
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("属性赋值之后调用");
}
/**
* 会在容器关闭的时候进行调用
*
* @throws Exception
*/
@Override
public void destroy() throws Exception {
System.out.println("调用销毁");
}
}
然后,在MainConfigByLifeCycle配置类中通过包扫描的方式将以上类注入到Spring容器中。
package com.zhz.config;
import com.zhz.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 生命周期相关配置
* @author zhouhengzhe
* @date 2022/11/21
*/
@Configuration
public class MainConfigByLifeCycle {
// @Scope("prototype")
@Bean
public Person person(){
return new Person();
}
}
让我们写一个测试类,代码如下:
@Test
public void test4ByLiseCycle(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigByLifeCycle.class);
System.out.println("容器创建完成");
Person bean = applicationContext.getBean(Person.class);
applicationContext.close();
}
首先我们创建一个对象,他实现了InitializingBean和DisposableBean,代码如下:
package com.zhz.bean;
import lombok.*;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/**
* @author zhouhengzhe
* @description: 实体类
* @date 2022/11/4 10:12
* @since v1
*/
@Data
@AllArgsConstructor
@Builder
public class Person implements InitializingBean, DisposableBean {
private String name;
private Integer age;
public Person() {
System.out.println("初始化构造方法");
}
/**
* 会在bean创建完成,并且属性都赋好值以后进行调用
*
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("属性赋值之后调用");
}
/**
* 会在容器关闭的时候进行调用
*
* @throws Exception
*/
@Override
public void destroy() throws Exception {
System.out.println("调用销毁");
}
}
然后,在MainConfigByLifeCycle配置类中通过包扫描的方式将以上类注入到Spring容器中。
package com.zhz.config;
import com.zhz.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 生命周期相关配置
* @author zhouhengzhe
* @date 2022/11/21
*/
@Configuration
public class MainConfigByLifeCycle {
@Scope("prototype")
@Bean
public Person person(){
return new Person();
}
}
让我们写一个测试类,代码如下:
@Test
public void test4ByLiseCycle(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigByLifeCycle.class);
System.out.println("容器创建完成");
Person bean = applicationContext.getBean(Person.class);
applicationContext.close();
}