单例默认情况下是在容器被加载的时候就会初始化 多例是在每次获取Bean对象的时候初始化
代码验证:
@Component
public class UserEntity {
public UserEntity() {
System.out.println(">>>>UserEntity无参数构造函数执行...");
}
@Configuration
@ComponentScan("com.mayikt.entity")
public class MyConfig {
}
>>>>UserEntity无参数构造函数执行...
当加上@Scope("prototype"),没有输出结果
@Component
@Scope("prototype")
public class UserEntity {
public UserEntity() {
System.out.println(">>>>UserEntity无参数构造函数执行...");
}
说明单例默认是在容器被加载的时候初始化,多例是在每次获取Bean对象的时候初始化。
Bean初始化:指的就是对象已经创建,里面的所有set方法都已经执行完毕了。
举个例子:
@Configuration
@ComponentScan("com.mayikt.entity")
public class MyConfig {
/**
* initMethod:指定初始化方法执行
* destroyMethod:指定销毁方法
* @return
*/
@Bean(initMethod = "initMethod",destroyMethod = "destroyMethod")
public UserEntity userEntity(){
return new UserEntity();
}
}
@Component
public class UserEntity {
public UserEntity() {
System.out.println(">>>>UserEntity无参数构造函数执行...");
}
/**
* 思考:initMethod是在无参构造函数之前执行还是后执行..
*/
private void initMethod() {
System.out.println(">>>>UserEntity initMethod 执行...");
}
private void destroyMethod() {
System.out.println(">>>>UserEntity destroyMethod 执行...");
}
}
public static void main(String[] args) {
/**
* IOC容器初始化单例对象都是循环遍历调用getBean方法
*/
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
applicationContext.close();
返回结果
>>>>UserEntity无参数构造函数执行... >>>>UserEntity initMethod 执行... >>>>UserEntity destroyMethod 执行...
构造函数:Bean的创建,Map集合存储对象 initMethod:表示对象已经创建成功之后执行 destroyMethod:表示对象被销毁之后执行,clean
分析下源码
applicationContext.close();
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
// If we registered a JVM shutdown hook, we don't need it anymore now:
// We've already explicitly closed the context.
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
catch (IllegalStateException ex) {
// ignore - VM is already shutting down
}
}
}
}
protected void doClose() {
if (this.active.get() && this.closed.compareAndSet(false, true)) {
if (logger.isInfoEnabled()) {
logger.info("Closing " + this);
}
LiveBeansView.unregisterApplicationContext(this);
try {
// Publish shutdown event.
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
// Stop all Lifecycle beans, to avoid delays during individual destruction.
try {
getLifecycleProcessor().onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
// Destroy all cached singletons in the context's BeanFactory.
destroyBeans();
// Close the state of this context itself.
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();
this.active.set(false);
}
}
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
public void destroySingletons() {
super.destroySingletons();
this.manualSingletonNames.clear();
this.clearByTypeCache();
}
private void clearByTypeCache() {
this.allBeanNamesByType.clear();
this.singletonBeanNamesByType.clear();
}
上面执行了clear操作,再回到前面
这里给用户自定义关闭操作:模板方法设计模式
protected void onClose() {
// For subclasses: do nothing by default.
}
再把活跃状态设置为false。
@Component
public class MemberEntity implements InitializingBean,DisposableBean{
// implements InitializingBean, DisposableBean
public MemberEntity() {
System.out.println("无参构造函数执行..");
}
// afterPropertiesSet initMet hod
// 1.对象创建 对象属性赋值 set方法全部走完
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("MemberEntity >>>afterPropertiesSet");
}
@Override
public void destroy() throws Exception {
System.out.println("MemberEntity >>> destroy");
}
}
输出结果:
无参构造函数执行.. MemberEntity >>>afterPropertiesSet MemberEntity >>> destroy
@Component
public class MemberEntity{
// implements InitializingBean, DisposableBean
public MemberEntity() {
System.out.println("无参构造函数执行..");
}
// afterPropertiesSet initMet hod
// 1.对象创建 对象属性赋值 set方法全部走完
@PostConstruct
public void afterPropertiesSet() throws Exception {
System.out.println("MemberEntity >>>afterPropertiesSet");
}
@PreDestroy
public void destroy() throws Exception {
System.out.println("MemberEntity >>> destroy");
}
}
输出结果
无参构造函数执行.. MemberEntity >>>afterPropertiesSet MemberEntity >>> destroy
SpringBean生命周期有个很好的理念
BeanPostProcessor引入:
@Component
public class MyApplicationContext implements ApplicationContextAware {
private ApplicationContext applicationContext;
/**
* spring底层中为什么能够实现ApplicationContextAware接口 就能够拿到ApplicationContext
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
MemberEntity memberEntity = applicationContext.getBean("memberEntity", MemberEntity.class);
System.out.println("memberEntity:" + memberEntity);
}
}
@Configuration
@ComponentScan("com.mayikt.entity")
@Import(MyApplicationContext.class)//这里注入到spring容器中
public class MyConfig {}
输出结果:对象初始化,赋值完毕,就可以通过setApplicationContext拿到bean对象
memberEntity:com.mayikt.entity.MemberEntity@11e21d0e
思考问题:spring底层中为什么能够实现ApplicationContextAware接口 就能够拿到ApplicationContext
靠的就是:BeanPostProcessor
下面开始分析:BeanPostProcessor后置处理器(非常重要!!!)
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
....
try {
....
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);//这里
}
....
}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
....
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();//这里
}
public void preInstantiateSingletons() throws BeansException {
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
while(true) {
String beanName;
RootBeanDefinition bd;
do {
do {
do {
if (!var2.hasNext()) {
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
Object singletonInstance = this.getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
return;
}
beanName = (String)var2.next();
bd = this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract());
} while(!bd.isSingleton());
} while(bd.isLazyInit());
if (this.isFactoryBean(beanName)) {
FactoryBean<?> factory = (FactoryBean)this.getBean("&" + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = (Boolean)AccessController.doPrivileged(() -> {
return ((SmartFactoryBean)factory).isEagerInit();
}, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
} else {
this.getBean(beanName);
}
}
}
}
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
Object sharedInstance = this.getSingleton(beanName);//查找缓存中有没有
判断是单例:
this.populateBean(beanName, mbd, instanceWrapper);//循环给属性赋值
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);//执行自定义的init方法
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) { //判断类型并设置beanName
((BeanNameAware)bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = this.getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware)bean).setBeanFactory(this);
}
}
}
我们就明白了:IOC容器初始化单例对象都是循环遍历调用getBean方法。
下面我们手写看下springBean的生命周期
@Component
public class PayEntity implements BeanNameAware, BeanFactoryAware, InitializingBean, ApplicationContextAware {
public PayEntity() {
System.out.println("1.对象的实例化完成..");
}
@Override
public void setBeanName(String name) {
System.out.println("2.对象beanName:" + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("3.beanFactory:" + beanFactory);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("4.获取到applicationContext对象");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("5.bean init方法执行..");
}
输出结果
1.对象的实例化完成..
2.对象beanName:payEntity
3.beanFactory:org.springframework.beans.factory.support.DefaultListableBeanFactory@55f3ddb1: defining beans [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,myConfig,payEntity]; root of factory hierarchy
4.获取到applicationContext对象
5.bean init方法执行..
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);//init之前处理操作
}
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);//init执行逻辑
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//init之后处理操作
}
return wrappedBean;
}
我们自己写个类实现BeanPostProcessor
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
//BeanPostProcessor 后置处理器 对我们bean的对象实现增强
@Override
// 执行自定义init方法之前处理
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行init方法之前处理 : " + beanName);
return bean;
}
@Override
// 执行自定义init方法之后处理
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行init方法之后处理 :" + beanName);
return bean;
}
//BeanPostProcessor 后置处理
// Aware 实现
}
结果
执行init方法之前处理 : org.springframework.context.event.internalEventListenerProcessor
执行init方法之后处理 :org.springframework.context.event.internalEventListenerProcessor
执行init方法之前处理 : org.springframework.context.event.internalEventListenerFactory
执行init方法之后处理 :org.springframework.context.event.internalEventListenerFactory
执行init方法之前处理 : myConfig
执行init方法之后处理 :myConfig
1.对象的实例化完成..
2.对象beanName:payEntity
3.beanFactory:org.springframework.beans.factory.support.DefaultListableBeanFactory@55f3ddb1: defining beans [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,myConfig,payEntity,com.mayikt.processor.MyBeanPostProcessor]; root of factory hierarchy
4.获取到applicationContext对象
执行init方法之前处理 : payEntity
5.bean init方法执行..
执行init方法之后处理 :payEntity
实现ApplicationAware接口怎么就可以setApplicationContext呢?
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("4.获取到applicationContext对象");
}
去后置处理器找
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
发现postProcessAfterInitialization没有做什么,再去前置找:
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {//判断ApplicationContextAware类型,赋值
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
所以我们知道ApplicationContextAware是通过前置实现的。
源码分析流程:
1、执行refresh()刷新方法 2、finishBeanFactoryInitialization(beanFactory); 3、beanFactory.preInstantiateSingletons(); 4、getBean(beanName)->doGetBean()->createBean()->doCreateBean()->createBeanInstance()初始化对象(默认情况下使用Java反射机制初始化对象,也可以通过CGLIB) 5、initializeBean() 6、invokeAwareMethods()判断是否有Aware接口依赖信息 7、applyBeanPostProcessorsBeforeInitialization()执行前置处理 8、invokeInitMethods()执行init()方法 8、applyBeanPostProcessorsAfterInitialization()执行后置处理