单例和多例
- 单例默认在容器创建的时候就会初始化,容器关闭的时候销毁
- 多例在使用对象的时候才会初始化
生命周期
调用无参构建函数创建对象—对象初始化—对象销毁
对象的初始化和销毁过程
自定义对象的初始化操作和对象销毁的操作,单例的销毁是在容器关闭的时候才会把对象销毁
下面展示第一种使用@Bean注解指定初始和销毁方法代码
。
package com.mayikt.v4.entity;
/**
* @Description:
* @Author: ChenYi
* @Date: 2020/07/03 07:25
**/
public class SmsEntity {
public SmsEntity() {
System.out.println("无参构造函数执行》》》》");
}
public void init() {
System.out.println("对象初始化>>>");
}
public void destroy() {
System.out.println("对象销毁>>>>");
}
}
package com.mayikt.v4.config;
import com.mayikt.v4.entity.SmsEntity;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @Description: spring配置类
* @Author: ChenYi
* @Date: 2020/07/02 23:07
**/
@Configuration
@ComponentScan("com.mayikt.v4")
public class MySpringConfig {
@Bean(initMethod = "init",destroyMethod = "destroy")
public SmsEntity smsEntity() {
return new SmsEntity();
}
}
下面展示第二种 对象实现InitializingBean初始化和DisposableBean销毁的代码
package com.mayikt.v4.entity;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
/**
* @Description:
* @Author: ChenYi
* @Date: 2020/07/04 14:16
**/
@Component
public class MemberEntity implements InitializingBean, DisposableBean {
public MemberEntity() {
System.out.println("无参构造函数执行>>>>");
}
@Override
public void destroy() throws Exception {
System.out.println("容器销毁>>>>");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("容器初始化>>>>>");
}
}
下面展示第三种 添加@PostConstruct初始和@PreDestroy销毁注解的代码
。
package com.mayikt.v4.entity;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* @Description:
* @Author: ChenYi
* @Date: 2020/07/04 14:20
**/
@Component
public class OrderEntity {
public OrderEntity() {
System.out.println("无参构造函数执行>>>>");
}
@PostConstruct
public void init() {
System.out.println("对象初始化>>>");
}
@PreDestroy
public void destroy() {
System.out.println("对象销毁>>>>");
}
}
ApplicationContextAware接口
自定义实现ApplicationContextAware接口获取ioc容器
package com.mayikt.v4.config;
import com.mayikt.v4.entity.OrderEntity;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @Description:
* @Author: ChenYi
* @Date: 2020/07/04 14:38
**/
@Component
public class MyApplicationContextAware implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
@Autowired
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
MyApplicationContextAware.applicationContext = applicationContext;
getBean();
}
public void getBean() {
OrderEntity orderEntity = MyApplicationContextAware.applicationContext.getBean("orderEntity", OrderEntity.class);
System.out.println(orderEntity);
}
}
整个bean生命周期的详细流程图
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//检查是否偶Aware依赖
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//调用BeanPostProcessorsBeforeInitialization方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//调用初始化的方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//调用BeanPostProcessorsAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
Aware接口
重要的接口:
BeanNameAware :可以获取容器中bean的名称
BeanFactoryAware:获取当前BeanFactory,可以调用容器的服务
ApplicationContextAware: 当前的applicationContext, 可以调用容器的服务
类图:
下面 自定义实现生命周期的接口代码
。
实现 DisposableBean BeanNameAware BeanFactoryAware ApplicationContextAware InitializingBean的接口
package com.mayikt.v4.entity;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @Description:
* @Author: ChenYi
* @Date: 2020/07/04 14:16
**/
@Component
public class MemberEntity implements DisposableBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean {
public MemberEntity() {
System.out.println("1.对象创建>>>>");
}
@Override
public void destroy() throws Exception {
System.out.println("8. 容器销毁>>>>");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("3.实现BeanFactoryAware接口" + beanFactory);
}
@Override
public void setBeanName(String name) {
System.out.println("2.实现BeanNameAware接口" + name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("4.实现ApplicationContextAware的接口");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("6.容器自定义init初始化>>>>>");
}
}
实现BeanPostProcessor接口
package com.mayikt.v4.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @Description:
* @Author: ChenYi
* @Date: 2020/07/04 16:08
**/
public class MyBeanPostProcess implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("5.执行init方法之前执行:" + beanName);
return beanName;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("7.执行init方法之后执行:" + beanName);
return beanName;
}
}
参考:蚂蚁课堂