目录
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的后置处理器
- BeanFactoryPostProcessor需要在BeanFactory组建完成后才起作用。
比如说,spring扫描后将生产的BeanDefinition都放到了BeanFactory的BeanDefinitionMap中。
当BeanFactory将需要的这些属性(BeanDefinitionMap、singletonObjects、beanDefinitionNames等)组建完成后,开始BeanFactoryPostProcessor操作 - 在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流程创建一个代理对象。
- beanFactory.registerSingleton(“XX”,XX)可以将一个java对象注册到单例池中,成为spring-bean
- 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