spring---bean的生命周期


  beanFactory容器启动之后,首先解析配置文件,生成并注册beanDefinition对象。beanDefinition包含了bean的实例化阶段所必需的信息。只有通过getBean方法来获取某个对象的实例使,容器才实例化这个对象。这一点更ApplicationContext容器不同,在getBean方法调用之前就将所有的类实例化。但是这两个容器都有一个特点,只要实例化一个对象,并且这个对象是单例模式,那么容器就有指向这个对象的引用,该对象的生命周期就由容器管理。接下来将详细介绍bean的生命周期的各个阶段。

Bean实例化过程图

在这里插入图片描述

实例化bean对象

  容器实例化bean是采用“策略模式”来决定采用何种方式来初始化bean实例。可以通过反射或CGLIB动态字节码来生成初始化相应bean实例或则动态生成其子类。InstantiationStrategy接口定义了实例化策略的抽象接口。其子类SimpleInstantiationStrategy实现了简单的对象实例化功能,可以通过反射来支持对象实例化,但不支持方法注入方式。CglibSubclassInstantiationStrategy继承了SimpleInstantiationStrategy类的以反射方式来实例化对象,并且使用cglib动态字节码生成技术,动态生成某个类的子类,从而支持方法注入方式。实例化之后,并不是直接返回bean对象,而是返回一个BeanWrapper对象,该对象封装了bean实例。之所以封装成BeanWrapper对象,是方便第二部的为对象赋值的操作。
  InstantiationStrategy接口方法全是对象实例化方法,入参都含有BeanDefinition对象。可以看出,spring容器实例化对象都要使用BeanDefinition对象。
  如果对方法注入不是很熟悉,请点击这里

public interface InstantiationStrategy {
    Object instantiate(RootBeanDefinition var1, String var2, BeanFactory var3) throws BeansException;

    Object instantiate(RootBeanDefinition var1, String var2, BeanFactory var3, Constructor<?> var4, Object... var5) throws BeansException;

    Object instantiate(RootBeanDefinition var1, String var2, BeanFactory var3, Object var4, Method var5, Object... var6) throws BeansException;
}

  InstantiationStrategy接口实现图:
在这里插入图片描述
  SimpleInstantiationStrategy类的instantiate方法解析:

public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
        if (bd.getMethodOverrides().isEmpty()) {
            Constructor constructorToUse;
            synchronized(bd.constructorArgumentLock) {
            	//获取配置文件中设置的构造器方法
                constructorToUse = (Constructor)bd.resolvedConstructorOrFactoryMethod;
                if (constructorToUse == null) {
                	//获取beanDefinition对象中的类对象
                    final Class<?> clazz = bd.getBeanClass();
                    //如果类对象是接口则抛出异常
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }
				
                    try {
                        if (System.getSecurityManager() != null) {
                            constructorToUse = (Constructor)AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
                                public Constructor<?> run() throws Exception {
                                	//调用class对象的无参构造器,使用java反射机制实例化对象
                                    return clazz.getDeclaredConstructor((Class[])null);
                                }
                            });
                        } else {
                            constructorToUse = clazz.getDeclaredConstructor((Class[])null);
                        }

                        bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                    } catch (Throwable var9) {
                        throw new BeanInstantiationException(clazz, "No default constructor found", var9);
                    }
                }
            }
			/调用class对象的无参构造器,使用java反射机制实例化对象
            return BeanUtils.instantiateClass(constructorToUse, new Object[0]);
        } else {
        	//使用方法注入方式注入属性,在SimpleInstantiationStrategy类中调用此方法会抛出异常,SimpleInstantiationStrategy不支持方法注入方式
            return this.instantiateWithMethodInjection(bd, beanName, owner);
        }
    }

  CglibSubclassCreator是CglibSubclassingInstantiationStrategy的内部类,其功能是创间bean实例,支持方法注入

    private static class CglibSubclassCreator {
        private static final Class<?>[] CALLBACK_TYPES = new Class[]{NoOp.class, CglibSubclassingInstantiationStrategy.LookupOverrideMethodInterceptor.class, CglibSubclassingInstantiationStrategy.ReplaceOverrideMethodInterceptor.class};
        private final RootBeanDefinition beanDefinition;
        private final BeanFactory owner;

        CglibSubclassCreator(RootBeanDefinition beanDefinition, BeanFactory owner) {
            this.beanDefinition = beanDefinition;
            this.owner = owner;
        }

        public Object instantiate(Constructor<?> ctor, Object... args) {
            Class<?> subclass = this.createEnhancedSubclass(this.beanDefinition);
            Object instance;
            if (ctor == null) {
            	//如果没传构造器,则使用子类的无参构造器创建实例
                instance = BeanUtils.instantiateClass(subclass);
            } else {
                try {
                	//根据传入的构造器,查找子类的对应构造器
                    Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
                    //使用子类有参构造器,通过反射创建实例
                    instance = enhancedSubclassConstructor.newInstance(args);
                } catch (Exception var6) {
                    throw new BeanInstantiationException(this.beanDefinition.getBeanClass(), "Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", var6);
                }
            }

            Factory factory = (Factory)instance;
            //设置回调
            factory.setCallbacks(new Callback[]{NoOp.INSTANCE, new CglibSubclassingInstantiationStrategy.LookupOverrideMethodInterceptor(this.beanDefinition, this.owner), new CglibSubclassingInstantiationStrategy.ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
            return instance;
        }
		//创建增强代理类
        private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(beanDefinition.getBeanClass());
            enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            if (this.owner instanceof ConfigurableBeanFactory) {
                ClassLoader cl = ((ConfigurableBeanFactory)this.owner).getBeanClassLoader();
                enhancer.setStrategy(new CglibSubclassingInstantiationStrategy.ClassLoaderAwareGeneratorStrategy(cl));
            }

            enhancer.setCallbackFilter(new CglibSubclassingInstantiationStrategy.MethodOverrideCallbackFilter(beanDefinition));
            enhancer.setCallbackTypes(CALLBACK_TYPES);
            return enhancer.createClass();
        }
    }

属性设置

  初始化bean之后,返回的是bean的包装对象BeanWrapperImpl对象,BeanWrapperImpl类间接实现了PropertyAccessor接口和TypeConverter接口,其中PropertyAccessor接口是用来为对象设置属性和获取属性值得。

public interface PropertyAccessor {
    String NESTED_PROPERTY_SEPARATOR = ".";
    char NESTED_PROPERTY_SEPARATOR_CHAR = '.';
    String PROPERTY_KEY_PREFIX = "[";
    char PROPERTY_KEY_PREFIX_CHAR = '[';
    String PROPERTY_KEY_SUFFIX = "]";
    char PROPERTY_KEY_SUFFIX_CHAR = ']';

    boolean isReadableProperty(String var1);

    boolean isWritableProperty(String var1);

    Class<?> getPropertyType(String var1) throws BeansException;

    TypeDescriptor getPropertyTypeDescriptor(String var1) throws BeansException;

    Object getPropertyValue(String var1) throws BeansException;

    void setPropertyValue(String var1, Object var2) throws BeansException;

    void setPropertyValue(PropertyValue var1) throws BeansException;

    void setPropertyValues(Map<?, ?> var1) throws BeansException;

    void setPropertyValues(PropertyValues var1) throws BeansException;

    void setPropertyValues(PropertyValues var1, boolean var2) throws BeansException;

    void setPropertyValues(PropertyValues var1, boolean var2, boolean var3) throws BeansException;
}

使用接口的复制方法,只要指定属性名称和属性值,便可以为接口中的包装对象设置值,因为不用j直接使用java 反射api就可以简单实现。大大简化了属性赋值操作。

检测Aware接口实现类

  当对象实例化后,并完成相关属性设置,spring容器开始检测该bean是否实现了Aware接口,,如果实现了Aware接口,则将接口规定的依赖注入给当前对象。Aware接口为如下几个:

  1. BeanNameAware:会将对象实例对应的bean定义对应的beanName设置到当前对象中去。
  2. BeanClassLoaderAware:将加载当前bean的classLoader设置到对象中去。
  3. BeanFactoryAware:beanFactory容器会将自身设置到当前对象中去
  4. ResourceLoaderAware:ApplicationContext会将自身设置到当前对象中去。
  5. ApplicationEventPublisherAware:会将ApplicationEventPublisher设置到当前对象中去(ApplicationContext实现了ApplicationEventPublisher接口,因此这时候ApplicatonContext容器会将自身设置到当前对象中去)。
  6. MessageSourceAware:将MessageSource对象设置到当前实例中去(ApplicationContext实现了MessageSource接口,因此这时候ApplicatonContext容器会将自身设置到当前对象中去)
  7. ApplicationContextAware:会将自身设置到当前对象中去。
      上面的这些规则读起来十分绕缺口,简单来说,如果你定义了一个类,在对象的使用过程中你会用到BeanFactory对象,那么你就只需要实现BeanFactoryAware接口,同时在定义的类中增加一个BeanFactory属性。由于你实现了BeanFactoryAware接口,因此自定义类中也会有一个接口方法setBeanFactory(BeanFactory var1),在该方法中,你字需要将传入的参数赋给自定义类的对应属性即可。自定义类实例化完成后,容器会自动调用该方法,完成属性的赋值工作。代码如下:
public class People implements BeanFactoryAware {
    private BeanFactory beanFactory;
    //容器会自动调用该方法,完成赋值工作
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
}

BeanPostProcessor接口

  讲到BeanPostProcessor接口,首先要和BeanFactoryPostProcessor接口区分开来,想了解BeanFactoryPostProcessor接口的朋友请点击这里,BeanPostProcessor接口方法调用时在对象实例化之后,而BeanFactoryPostProcessor接口方法调用是在容器启动阶段,对所有满足条件的beanDefinition做操作,此时bean还没有实例化。BeanPostProcessor接口又两个接口方法,分别为:postProcessBeforeInitialization(又称为前置处理方法),postProcessAfterInitialization(又称为后置处理方法)。两个方法都将bean实例的引用当做参数传入。

public interface BeanPostProcessor {
	//前置处理方法
    Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;
	//后置处理方法
    Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}

  BeanPostProcessor接口通常用来处理标记接口实现类或则为当前接口实现代理。上面讲的Aware接口处理实际上就是使用BeanPostProcessor方式进行处理的。当容器中的对象走到BeanPostProcessor的前置处理器这一步时,ApplicationContext容器就会检测之前注册到容器中的ApplicationContextAwareProcessor类(此类是BeanPostProcessor接口的实现类),然后调用前置处理方法,检测并设置Aware相关依赖。

public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
		AccessControlContext acc = null;

		if (System.getSecurityManager() != null &&
				(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
						bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
						bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					//检测Aware接口并设置相关依赖
					invokeAwareInterfaces(bean);
					return null;
				}
			}, acc);
		}
		else {
			//检测Aware接口并设置相关依赖
			invokeAwareInterfaces(bean);
		}

		return bean;
	}
private void invokeAwareInterfaces(Object bean) {
		//如果当前实例实现Aware接口
		if (bean instanceof Aware) {
			//如果实现
			if (bean instanceof EnvironmentAware) {
				//为当前实例设置environment依赖
				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
			}
			//如果实现EmbeddedValueResolverAware
			if (bean instanceof EmbeddedValueResolverAware) {
				//为当前实例设置embeddedValueResolver依赖
				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
			}
			//如果实现ResourceLoaderAware
			if (bean instanceof ResourceLoaderAware) {
				//为当前实例设置applicationContext依赖
				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
			}
			//如果实现ApplicationEventPublisherAware
			if (bean instanceof ApplicationEventPublisherAware) {
				//为当前实例设置applicationContext依赖
				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
			}
			//如果实现MessageSourceAware
			if (bean instanceof MessageSourceAware) {
				//为当前实例设置applicationContext依赖
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}
			//如果实现ApplicationContextAware
			if (bean instanceof ApplicationContextAware) {
				//为当前实例设置applicationContext依赖
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}

  BeanPostProcessor是spring为开发者提供的一个非常有用的拓展点,我们可以通过实现BeanPostProcessor接口,实现接口方法,从而对满足条件的bean实例进行修改或则替换,比如对当前对象进行增强操作。创建好自定义类之后,将该类注册到容器中即可。

检测是否为InitializingBean实现类

  这里手下说明一下,实现InitializingBean接口和在配置文件中配置init-method属性的作用是一样的,两者都是在执行完Aware接口处理之后,会调用InitializingBean实现类的afterPropertySet方法或者执行init-method指定的方法。但是通过实现InitializingBean接口的方式具有侵入性,因此在实际开发中,我们更倾向于使用init-method配置的方式。
  spring.xml配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <bean id="user" class="springBeanTest.User" init-method="init">
    </bean>
</beans>

  User类:

public class User {
    private String username;
    private String password;

    public void init(){
        this.username = "ranxiaochuan";
        this.password = "123";
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

  测试类

public class LifeCycleTest {
    @Test
    public void test1(){
        //创建bean的工厂类
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //创建一个xml文件的reader类,将bean工厂传入reader中
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) beanFactory);
        //加载xml未配置文件,并将配置文件解析成BeanDefinition对象保存在工厂类中
        reader.loadBeanDefinitions("classpath:/spring.xml");
        User user = (User) beanFactory.getBean("user");
        System.out.println(user.getPassword());
        System.out.println(user.getUsername());
    }
}

  测试结果:
在这里插入图片描述

BeanPostProcessor后置处理

  BeanPostProcessor后置处理跟BeanPostProcessor前置处理思路一样,只是调用时间有差别。这里就不再赘述。

检查是否实现DisposableBean接口或则是否配置destroy方法

  实现DisposableBean接口和配置destroy方法的作用是一样的,前者有侵入性,后者没有。他们的作用都是在对象销毁前做一些清理工作,比如说对与数据库连接对象,在销毁之前应该关闭数据库连接。这里需要主要一点,无论是BeanFactory容器还是ApplicationContext容器,如果要调用销毁方法,都必须在主程序执行结束之前显示的调用容器的销毁方法。BeanFactory容器调用distroySingletons()方法;ApplicationContext容器调用registerShutDownHook()方法。到此,bean的生命周期就结束了。

发布了3 篇原创文章 · 获赞 5 · 访问量 122

猜你喜欢

转载自blog.csdn.net/ranxiaochuan1994/article/details/105249291