Spring生命周期

1. 普通java对象的创建过程

在这里插入图片描述
普通java对象是直接通过new出来的,spring bean不仅仅是java对象,而是经过了spring的流程的对象。

2. Spring-bean生命周期流程

重要!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

================以scope为singleton为示例:
先创建容器 createBeanFactory()
/
xml或者注解形式的bean -->
/
BeanDefinition(包扫描,生成后被放到beanFactory的beanDefinitionMap中) -->
/
BeanFactoryPostProcessor :占位符替换等扩展功能在这里实现,最终生成一个最终的BeanDefinition;也可以人为修改BeanDefinition中的属性–>
/
通过BeanDefinition中的beanClass属性去创建原始对象 -->
/
填充属性 -->
/
spring会检测bean是否实现了Aware接口,有则回调Aware(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware等)–>
/
BeanPostProcessor.postProcessBeforeInitialization方法
/
InitializingBean.afterPropertiesSet(自己定义的初始化逻辑)–>
/
调用xml中指定的初始化方法:init-method
/
BeanPostProcessor.postProcessAfterInitialization -->
/
aop(其实是在在某个后置处理器的执行阶段完成) -->
/
放到单例池
1. 不开启aop:Map<String BeanName,Object spring-bean>
2. 开启aop: Map<String BeanName,Object spring-bean的代理对象> -->
/
getBean从单例池中获取bean -->
/
销毁bean
1)当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了DisposableBean 这个接口,会调用其实现的 destroy()方法
2)如果这个 Bean 的 Spring 配置中配置了destroy-method 属性,会 自动调用其配置的销毁方法。

重要!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
在这里插入图片描述
在BeanFactory接口中有描述生命周期:

* <p>Bean factory implementations should support the standard bean lifecycle interfaces
 * as far as possible. The full set of initialization methods and their standard order is:
 * <ol>
 * <li>BeanNameAware's {@code setBeanName}
 * <li>BeanClassLoaderAware's {@code setBeanClassLoader}
 * <li>BeanFactoryAware's {@code setBeanFactory}
 * <li>EnvironmentAware's {@code setEnvironment}
 * <li>EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
 * <li>ResourceLoaderAware's {@code setResourceLoader}
 * (only applicable when running in an application context)
 * <li>ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
 * (only applicable when running in an application context)
 * <li>MessageSourceAware's {@code setMessageSource}
 * (only applicable when running in an application context)
 * <li>ApplicationContextAware's {@code setApplicationContext}
 * (only applicable when running in an application context)
 * <li>ServletContextAware's {@code setServletContext}
 * (only applicable when running in a web application context)
 * <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
 * <li>InitializingBean's {@code afterPropertiesSet}
 * <li>a custom init-method definition
 * <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
 * </ol>

3. BeanDefinition

spring-bean,不管是xml形式还是注解形式,都需要先读取进行解析,成为一个BeanDefinition对象,这个BeanDefinition对象会被放到一个map中(beanDefinitionMap)

BeanDefinition:用于存储定义bean的元数据,包括了
1. 初始化方法的名字–initMethodName
2. 构造方法参数值–constructorArgumentValues -->会根据这个参数的不同调用不同的构造函数
3. 父类名称–parentName
4. 是否懒加载–lazyInit
5. 是否是单例–scope 默认为singleton
6. bean的类名–beanClass 全限定类名
7. 注入模式–autowireMode byName还是byType注入
8. 描述信息等

@Component
@Data
public class Book {
    private User user;
    public Book(){
        System.out.println("Book初始化实例");
    }
}
@Component
@Data
public class User {
    private Book book;
    public User(){
        System.out.println("User初始化实例");
    }
}
测试代码:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
String[] beanDefinitionNames = context.getBeanDefinitionNames();  //获取此时容器中的BeanDefinition名称
for (String item : beanDefinitionNames) {
    System.out.println(item);
}
========output:
Book初始化实例
User初始化实例
book    //自己定义的bean
user    //自己定义的bean
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
org.springframework.aop.config.internalAutoProxyCreator

beanDefinitionMap:
在这里插入图片描述

BeanDefinition:
在这里插入图片描述

4. BeanFactory

用于生成和获取bean
在这里插入图片描述

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = context.getBean("user", User.class);  //ApplicationContext是BeanFactory的扩展,context.getBean其实是调用了beanFactory.getBean方法

beanFactory中包含的属性:beanDefinitionMap、beanDefinitionNames、singletonObjects(单例池)等
在这里插入图片描述
在这里插入图片描述

5. BeanFactoryPostProcessor–beanFactory的后置处理器

  1. BeanFactoryPostProcessor需要在BeanFactory组建完成后才起作用
    比如说,spring扫描后将生产的BeanDefinition都放到了BeanFactory的BeanDefinitionMap中。
    当BeanFactory将需要的这些属性(BeanDefinitionMap、singletonObjects、beanDefinitionNames等)组建完成后,开始BeanFactoryPostProcessor操作
  2. 在bean被实例化之前,spring提供BeanFactoryPostProcessor用于扩展功能
    类比:受精卵(BeanDefinition)-------->基因工程(BeanFactoryPostProcessor)--------->出生的婴儿(原始bean)----…----->成人(spring-bean)
@Data  //原先的@Component被去掉,使Book不被扫描,无法成为spring的bean
public class Book {
    private User user;
    public Book(){
        System.out.println("Book初始化实例");
    }
}
@Component
@Data
public class User {
    private Book book;
    public User(){
        System.out.println("User初始化实例");
    }
}
========测试代码:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
context.getBean(Book.class);  //报错
=======output:
No qualifying bean of type 'com.jarvis.Book' available

使用自定义BeanFactoryPostProcessor修改生成的对象:

@Component   //用于被spring管理,才能生效
public class jarvisBeanFactoryPostProcesser implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        GenericBeanDefinition bd = (GenericBeanDefinition)beanFactory.getBeanDefinition("user");
        bd.setBeanClass(Book.class);  //修改BeanDefinition对象中的beanClass属性,使得将要生成的对象由User改为Book类
    }
}
注:
、、、
beanFactory.getBeanDefinition其实执行的代码是DefaultListableBeanFactory类的如下方法:
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
   BeanDefinition bd = this.beanDefinitionMap.get(beanName);  //这里可以验证:BeanDefinition是从beanDefinitionMap这个map中取出的
   ...
}
、、、
========测试代码:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String item : beanDefinitionNames) {
    System.out.println(item);
}
context.getBean(Book.class);   //未报错
============output:
Book初始化实例   //执行的是Book类对象的创建,虽然名字还是user
jarvisBeanFactoryPostProcesser   //自己定义的
user
...各种Processer...

6. beanFactory.getBean()执行时产生bean

在BeanFactoryPostProcessor执行期间,手动使用getBean方法,将原先下一步的创建bean提前:

@Component
public class jarvisBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        User bean = beanFactory.getBean(User.class); //这里其实是创建了一个bean放到了单例池中
    }
}

执行的是DefaultListableBeanFactory.getBean()方法:
在这里插入图片描述
在这里插入图片描述

7. 回调执行Aware

Aware接口可以在自定义bean中调用Spring容器内部的bean

public class Book implements BeanNameAware, BeanFactoryAware , InitializingBean {
    @Value("三国")
    private String name;
    @Value("37")
    private Integer price;
    public Book(){
        System.out.println("Book初始化实例");
    }
    @Override
    public void setBeanName(String name) {
        System.out.println(name);  //可以知道spring给这个bean起的名字
        System.out.println("setBeanName==="+this.toString());
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println(beanFactory.toString());  //可以知道该bean是由哪个beanFactory创建的
        System.out.println("setBeanFactory==="+this.toString());
    }
    @Override
    public void afterPropertiesSet() throws Exception {  //如果实现了InitializingBean,在属性注入后进入这个方法,执行我们自己定义的初始化逻辑
        System.out.println("调用InitializingBean的afterPropertiesSet");
        System.out.println("afterPropertiesSet==="+this.toString());
    }
}
========测试代码:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
=======output:
Book初始化实例
book
setBeanName===Book(name=三国, price=37)
org.springframework.beans.factory.support.DefaultListableBeanFactory@662706a7: ......
setBeanFactory===Book(name=三国, price=37)
调用InitializingBean的afterPropertiesSet
afterPropertiesSet===Book(name=三国, price=37)
Aware接口是在属性注入之后回调执行的,执行顺序:
      BeanNameAware.setBeanName -->  
      BeanClassLoaderAware.setBeanClassLoader -->
      BeanFactoryAware.setBeanFactory --> 
      afterPropertiesSet.afterPropertiesSet

因为在调试过程中进入了AbstractAutowireCapableBeanFactory类的如下方法:

private void invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

8. AOP是IOC的一个扩展功能

AbstractAutoProxyCreateor类是BeanPostProcessor的一个抽象子类:

@Override
/**
	 * Create a proxy with the configured interceptors if the bean is
	 * identified as one to proxy by the subclass.
	 * @see #getAdvicesAndAdvisorsForBean
	 */
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (!this.earlyProxyReferences.contains(cacheKey)) {
		    //必要时创建代理对象
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	...
	// Create proxy if we have advice.  创建代理对象
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	if (specificInterceptors != DO_NOT_PROXY) {
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		Object proxy = createProxy(  //createProxy:创建代理的方法
				bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
		this.proxyTypes.put(cacheKey, proxy.getClass());
		return proxy;
	}

	this.advisedBeans.put(cacheKey, Boolean.FALSE);
	return bean;
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
		@Nullable Object[] specificInterceptors, TargetSource targetSource) {
	...
    //获取代理对象
	return proxyFactory.getProxy(getProxyClassLoader());
}

跳到ProxyFactory.getProxy方法:

public Object getProxy(@Nullable ClassLoader classLoader) {
	return createAopProxy().getProxy(classLoader);
}

跳到AopProxy接口:

Object getProxy(@Nullable ClassLoader classLoader);

AopProxy.getProxy的两种实现方式:
在这里插入图片描述

9. FactoryBean

FactoryBean首先是一个ioc容器中的spring-bean,它最大的一个作用是:可以让通过getObject方法自定义一个Bean的真实返回对象。
比如:Mybatis整合到Spring中时

public class UserService {
    private UserMapper userMapper;  
}

Spring需要将UserMapper的动态代理对象注入到UserSerivce的userMapper属性,而不是执行一整套正常的spring-bean流程创建一个代理对象。

  1. beanFactory.registerSingleton(“XX”,XX)可以将一个java对象注册到单例池中,成为spring-bean
  2. FactoryBean方式:Spring整合Mybatis使用的是这种方式
    Spring整合Mybatis之源码简单解析中有提到
第一种:FactoryBean的isSingleton()方法不重写,默认是单例模式,getObject()只执行一次
@Component
public class jarvisFactoryBean implements FactoryBean {
    @Override  
    public Object getObject() throws Exception {
        MyClass myClass = new MyClass();  //这里自己new的java对象会被放到单例池中。
        System.out.println(myClass);  
        return myClass;
    }
    @Override
    public Class<?> getObjectType() {
        return MyClass.class;
    }
}
======测试代码:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(context.getBean("jarvisFactoryBean", MyClass.class));
System.out.println(context.getBean("jarvisFactoryBean", MyClass.class));
System.out.println(context.getBean("jarvisFactoryBean", MyClass.class));
======output:
com.jarvis.MyClass@bcec361
com.jarvis.MyClass@bcec361
com.jarvis.MyClass@bcec361
com.jarvis.MyClass@bcec361


第二种:FactoryBean的isSingleton()方法重写,返回false,每次getBean()都会调用一次getObject()
@Component
public class jarvisFactoryBean implements FactoryBean {
    @Override 
    public Object getObject() throws Exception {
        MyClass myClass = new MyClass();
        System.out.println(myClass);
        return myClass;
    }
    @Override
    public Class<?> getObjectType() {
        return MyClass.class;
    }
    @Override
    public boolean isSingleton() {
        return false;
    }
}
======output:
com.jarvis.MyClass@bcec361
com.jarvis.MyClass@bcec361
com.jarvis.MyClass@26794848
com.jarvis.MyClass@26794848
com.jarvis.MyClass@302552ec
com.jarvis.MyClass@302552ec

10. 生命周期执行顺序测试

applicationContext.xml

<context:component-scan base-package="com.jarvis.XHYL"/>
    <context:annotation-config/>
    <!--开启基于注解的AOP功能:aop名称空间-->
    <aop:aspectj-autoproxy  />

    <bean id="bookService" class="com.jarvis.XHYL.BookService" init-method="play"/>
    <bean id="userService" class="com.jarvis.XHYL.UserService"/>

接口

public interface IBookService {
    void play();
}
public interface IUserService {
    void play();
}

实现类

public class BookService implements IBookService,BeanNameAware, BeanClassLoaderAware, BeanFactoryAware , InitializingBean {
    @Autowired
    private IUserService userService;
    @Override
    public void play() {
        System.out.println("BookService...init-method");
    }
    public IUserService getUserService() {
        return userService;
    }
    public void setUserService(IUserService userService) {
        this.userService = userService;
    }
    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("BookService***BeanClassLoaderAware.setBeanClassLoader");
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BookService***BeanFactoryAware.setBeanFactory");
    }
    @Override
    public void setBeanName(String name) {
        System.out.println("BookService***BeanNameAware.setBeanName");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("BookService***InitializingBean.afterPropertiesSet");
    }
}
public class UserService implements IUserService {
    @Autowired
    private IBookService bookService;
    public IBookService getBookService() {
        return bookService;
    }
    public void setBookService(IBookService bookService) {
        this.bookService = bookService;
    }
    @Override
    public void play() {
    }
}

切面类

@Component
@Aspect
public class LogUtils {
    @Before("execution(public void com.jarvis.XHYL.*.*())")
    public void logStart(){
        System.out.println("start");
    }
    @AfterReturning("execution(public void com.jarvis.XHYL.*.*())")
    public void logReturn(){
        System.out.println("return");
    }
    @AfterThrowing("execution(public void com.jarvis.XHYL.*.*())")
    public void logException(){
        System.out.println("exception");
    }
    @After("execution(public void com.jarvis.XHYL.*.*())")
    public void logAfter(){
        System.out.println("after");
    }
}

自定义BeanFactoryPostProcessor

@Component
public class jarvisBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryPostProcessor.postProcessBeanFactory");
    }
}

自定义BeanPostProcessor

@Component
public class jarvisBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName+"***BeanPostProcessor.postProcessBeforeInitialization");
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName+"***BeanPostProcessor.postProcessAfterInitialization");
        return null;
    }
}

执行顺序

BeanFactoryPostProcessor.postProcessBeanFactory
logUtils***BeanPostProcessor.postProcessBeforeInitialization
logUtils***BeanPostProcessor.postProcessAfterInitialization
org.springframework.context.event.internalEventListenerProcessor***BeanPostProcessor.postProcessBeforeInitialization
org.springframework.context.event.internalEventListenerProcessor***BeanPostProcessor.postProcessAfterInitialization
org.springframework.context.event.internalEventListenerFactory***BeanPostProcessor.postProcessBeforeInitialization
org.springframework.context.event.internalEventListenerFactory***BeanPostProcessor.postProcessAfterInitialization
userService***BeanPostProcessor.postProcessBeforeInitialization
userService***BeanPostProcessor.postProcessAfterInitialization
BookService***BeanNameAware.setBeanName
BookService***BeanClassLoaderAware.setBeanClassLoader
BookService***BeanFactoryAware.setBeanFactory
bookService***BeanPostProcessor.postProcessBeforeInitialization
BookService***InitializingBean.afterPropertiesSet
BookService***init-method
bookService***BeanPostProcessor.postProcessAfterInitialization

参考频详解:https://www.bilibili.com/video/BV1KC4y1t7x4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值