1.Bean生命周期简单概述 2.BeanPostProcessor作用 3.BeanPostProcessor实现增强 4.模拟手写BeanPostProcessor增强 5.常见后置处理器类型有哪些 6.@Autowired Bean后置处理器源码解读
第十期中----手写nacos config 分布式配置中心
刷新bean---设计spring bean生命周期
依赖BeanPostProcessor
IOC容器架构设计原理
周二 bean处理器底层架构设计
周四 bean生命周期原理总结---
周六 手写出 spring bean生命周期
spring bean生命周期 BeanPostProcessor
Bean生命周期概述1.Spring中的bean的生命周期主要包含四个阶段:实例化Bean --> Bean属性填充 --> 初始化Bean -->销毁Bean
2.首先是实例化Bean,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚末初始化的依赖时,容器就会调用doCreateBean()方法进行实例化,实际上就是通过反射的方式创建出一个bean对象
3.Bean实例创建出来后,接着就是给这个Bean对象进行属性填充,也就是注入这个Bean依赖的其它bean对象
属性填充完成后,进行初始化Bean操作,初始化阶段又可以分为几个步骤:
3.1执行Aware接口的方法
3.2.Spring会检测该对象是否实现了xxxAware接口,通过Aware类型的接口,可以让我们拿到Spring容器的些资源。如实现
3.3.BeanNameAware接口可以获取到BeanName,实现BeanFactoryAware接口可以获取到工厂对象BeanFactory等
3.4.执行BeanPostProcessor的前置处理方法postProcessBeforelnitialization(),对Bean进行一些自定义的前置处理
3.5.判断Bean是否实现了InitializingBean接口,如果实现了,将会执行lnitializingBean的afeterPropertiesSet()初始化方法;
3.6.执行用户自定义的初始化方法,如init-method等;
3.7.执行BeanPostProcessor的后置处理方法postProcessAfterinitialization()
初始化完成后,Bean就成功创建了,之后就可以使用这个Bean, 当Bean不再需要时,会进行销毁操作,
3.8首先判断Bean是否实现了DestructionAwareBeanPostProcessor接口,如果实现了,则会执行DestructionAwareBeanPostProcessor后置处理器的销毁回调方法
3.8其次会判断Bean是否实现了DisposableBean接口,如果实现了将会调用其实现的destroy()方法
3.9最后判断这个Bean是否配置了dlestroy-method等自定义的销毁方法,如果有的话,则会自动调用其配置的销毁方法;
为什么需要设计BeanPostProcessorBeanPostProcessor及其子类都实现了后置处理的功能。
1.其中postProcessBeforeInitialization方法会在每一个bean对象的初始化方法调用之前回调;2.postProcessAfterInitialization方法会在每个bean对象的初始化方法调用之后被回调。
相关代码:
package com.mayikt.postprocessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
//其中postProcessBeforeInitialization方法会在每一个bean对象的初始化方法调用之前回调;
/**
* 在调用init初始化之前 可以修改原有bean对象 如果返回是为null 则直接返回原有bean对象
*
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("mayiktBean".equals(beanName))
System.out.println("A before--实例化的bean对象:" bean "t" beanName);
return bean;
}
//postProcessAfterInitialization方法会在每个bean对象的初始化方法调用之后被回调。 可以修改原有bean对象 如果返回是为null 则直接返回原有bean对象
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("mayiktBean".equals(beanName))
System.out.println("A after...实例化的bean对象:" bean "t" beanName);
return bean;
}
}
---------------------------------------------------------------------------
package com.mayikt.entity;
import com.sun.org.slf4j.internal.Logger;
import com.sun.org.slf4j.internal.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* @author songchuanfu
* @qq 1802284273
*/
@Component
public class MayiktBean {
public MayiktBean() {
System.out.println("MayiktBean 构造方法执行...");
}
@Autowired
public void getUser(UserEntity userEntity1) {
System.out.println(" MayiktBean 依赖注入,userEntity:" userEntity1);
}
@PostConstruct
public void init() {
System.out.println(" MayiktBean init()...");
}
@PreDestroy
public void destroy() {
System.out.println("MayiktBean destroy()...");
}
}
@PostConstruct是Java自带的注解,在方法上加该注解会在项目启动的时候执行该方法,也可以理解为在spring容器初始化的时候执行该方法
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("mayiktBean".equals(beanName))
System.out.println("A before--实例化的bean对象:" bean "t" beanName);
return bean;
}
相关源码:
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 执行后置处理器 如果 后置处理器有返回bean对象 则使用 后置处理器返回bean对象
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
BeanPostProcessor处理器实现异步增强
package com.mayikt.postprocessor;
import com.mayikt.ext.MayiktAsync;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author songchuanfu
* @qq 1802284273
*/
@Component
public class AsyncPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 1.判断类上是否有加上MayiktAsync
MayiktAsync mayiktAsync = bean.getClass().getDeclaredAnnotation(MayiktAsync.class);
// 2.如果类上有加上mayiktAsync 走cglib代理 采用异步执行方法
if (mayiktAsync == null) {
return bean;
}
ExecutorService executorService = Executors.newFixedThreadPool(3);
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(bean.getClass());
enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
executorService.execute(new Runnable() {
@Override
public void run() {
try {
methodProxy.invokeSuper(o, objects);// 执行目标方法
} catch (Throwable throwable) {
}
}
});
return null;
});
return enhancer.create();
}
}
package com.mayikt.entity;
import com.mayikt.ext.MayiktAsync;
import com.sun.org.slf4j.internal.Logger;
import com.sun.org.slf4j.internal.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* @author songchuanfu
* @qq 1802284273
*/
@Component
@MayiktAsync
public class MayiktBean {
public MayiktBean() {
System.out.println("MayiktBean 构造方法执行...");
}
@Autowired
public void getUser(UserEntity userEntity1) {
System.out.println(" MayiktBean 依赖注入,userEntity:" userEntity1);
}
@PostConstruct
public void init() {
System.out.println(" MayiktBean init()...");
}
@PreDestroy
public void destroy() {
System.out.println("MayiktBean destroy()...");
}
public void add() {
System.out.println(Thread.currentThread().getName() ",...add()...");
}
}
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
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()) {
// 执行 bean处理器 初始化(init)方法之前
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 执行类中 初始化方法init()
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()) {
// // 执行 bean处理器 初始化(init)方法之后
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 执行bean处理器方法 如果返回值 null
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
// 返回就是原来bean对象
return result;
}
// 如果我们的 postProcessBeforeInitialization返回值
// 不为null的情况下 则将 返回值作为新对象
result = current;
}
return result;
}
自定义注解生效的情况下 代理模式
1.aop 反射模式
2.bean 处理器 改写原生bean对象为代理对象 走代理回调方法 目标方法前后实现增强。
BeanPostProcessor处理器封装底层原理在spring中提供了非常多的BeanPostProcessor
package com.mayikt.ext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
/**
* @author songchuanfu
* @qq 1802284273
*/
public class SpringApplicationContext {
private List<MayiktBeanPostProcessor> mayiktBeanPostProcessors = new ArrayList<>();
public SpringApplicationContext() {
mayiktBeanPostProcessors.add(new AutowiredMayiktBeanPostProcessor());
mayiktBeanPostProcessors.add(new ResourceMayiktBeanPostProcessor());
}
public void getBean(String name) throws BeansException {
//1.实例化Bean 执行无参构造方法
Object bean = new Object(); // 例如该对象从IOC容器中获取 bean对象
//2.Bean属性填充 --- @Autowired @Resource
mayiktBeanPostProcessors.forEach(beanPostProcessor -> {
beanPostProcessor.postProcessBeforeInitialization(bean, name);
});
//3.初始化Bean
//4.销毁Bean
System.out.println("返回bean对象");
}
interface MayiktBeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName);
}
class AutowiredMayiktBeanPostProcessor implements MayiktBeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
// 根据该bean 给该bean成员属性赋值
System.out.println(" Autowired 依赖注入成员属性赋值 beanName:" beanName);
return bean;
}
}
class ResourceMayiktBeanPostProcessor implements MayiktBeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
// 根据该bean 给该bean成员属性赋值
System.out.println(" Resource 依赖注入成员属性赋值beanName:" beanName);
return bean;
}
}
}
多个BeanPostProcessor处理器如何排序
实现Ordered
public class AsyncPostProcessor implements BeanPostProcessor , Ordered {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
重写getOrder方法 值越小越优先执行
@Override
public int getOrder() {
return 3;
}
常用BeanPostProcessor处理器AutowiredAnnotationBeanPostProcessor
1.AutowiredAnnotationBeanPostProcessor 处理Autowired注解
2.CommonAnnotationBeanPostProcessor 处理 处理@Resource @PostConstruct @PreDestroy
package com.mayikt.entity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
/**
* @author songchuanfu
* @qq 1802284273
*/
@Component
public class MemberEntity {
@Autowired
private OrderEntity order1;
private OrderEntity order2;
private OrderEntity order3;
@Autowired
public void setOrderEntity(OrderEntity orderEntity) {
System.out.println("@Autowired生效,setOrderEntity:" orderEntity);
this.order2 = orderEntity;
}
@Resource
public void setOrderEntity2(OrderEntity orderEntity) {
System.out.println("@Resource,orderEntity:" orderEntity);
this.order3 = orderEntity;
}
@PostConstruct
public void init() {
System.out.println(" MayiktBean init()...");
}
@PreDestroy
public void destroy() {
System.out.println("MayiktBean destroy()...");
}
public OrderEntity getOrder1() {
return order1;
}
}
package com.mayikt.entity;
import org.springframework.stereotype.Component;
/**
* @author songchuanfu
* @qq 1802284273
*/
@Component
public class OrderEntity {
}
// 1.创建轻量级 GenericApplicationContext
GenericApplicationContext applicationContext = new GenericApplicationContext();
// 2.注册bean对象
applicationContext.registerBean("memberEntity", MemberEntity.class);
applicationContext.registerBean("orderEntity", OrderEntity.class);
applicationContext.registerBean(AutowiredAnnotationBeanPostProcessor.class);//处理Autowired注解
applicationContext.registerBean(CommonAnnotationBeanPostProcessor.class);// 处理@Resource @PostConstruct @PreDestroy
// 3.初始化IOC容器 执行 后置处理器
applicationContext.refresh();
Arrays.stream(applicationContext.getBeanDefinitionNames()).forEach((b) -> {
System.out.println(b);
});
MemberEntity memberEntity = applicationContext.getBean("memberEntity", MemberEntity.class);
System.out.println(memberEntity.getOrder1());
applicationContext.close();
工厂处理器
bean后置处理器 bean额外增强功能
1.bean中成员属性赋值
2.注解生效 额外增强
ConfigurationClassPostProcessor 工厂处理器
package com.mayikt.test;
import com.mayikt.config.SpringConfig02;
import com.mayikt.entity.MemberEntity;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
import javax.security.auth.login.Configuration;
import java.util.Arrays;
/**
* @author songchuanfu
* @qq 1802284273
*/
public class Test03 {
public static void main(String[] args) {
// 1.创建轻量级 GenericApplicationContext
GenericApplicationContext applicationContext = new GenericApplicationContext();
// 2.注册bean对象
applicationContext.registerBean("springConfig02", SpringConfig02.class);
applicationContext.registerBean(ConfigurationClassPostProcessor.class);
// @ComponentScan("com.mayikt.entity") @Bean等 @Configuration
applicationContext.refresh();
Arrays.stream(applicationContext.getBeanDefinitionNames()).forEach((b) -> {
System.out.println(b);
});
}
}
相关代码
spring源码核心.rar