1、bean生命周期:看BeanFactory注释
翻译成中文
Bean工厂实现应该尽可能的支持标准的Bean生命周期接口。整套初始化方法及其标准顺序如下:
BeanNameAware{@code setBeanName}
BeanClassLoaderware{@code setBeanClassLoader}
BeanFactoryAware{@code setBeanFactory}
EnvironmentAware{@code setEnvironment}
EmbeddedValueResolverAware{@code setEmbeddedValueResolver}
ResourceLoaderware{@code setResourceLoader}(仅在应用程序上下文中运行时适用)
ApplicationEventPublisherAware{@code setApplicationEventPublisher}(仅在应用程序上下文中运行时适用)
MessageSourceAware{@code setMessageSource}(仅在应用程序上下文中运行时适用)
ApplicationContextAware{@code setApplicationContext}(仅在应用程序上下文中运行时适用)
ServletContextAware{@code setServletContext}(仅在web应用程序上下文中运行时适用)
BeanPostProcessor{@code postprocessabefore initialization}方法
初始化Bean的{@code afterPropertieSet}自定义init方法定义
BeanPostProcessor{@code postProcessAfterInitialization}方法
关闭Bean工厂时,以下生命周期方法适用:
{@code postprocessabeforedisplation}销毁方法Warebean后处理器
DisposableBean的{@code destroy}
自定义销毁方法
2、Aware接口的作用:可以理解为是个插件,如果自己创建的bean对象需要容器的内置对象,可以通过Aware接口把对象设置到这个bean里
查看代码
package beans;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* 只要实现Aware接口,就可自动注入容器内置的某些属性,比如注入ApplicationContext、beanName
*/
public class MyAwareBean implements ApplicationContextAware, BeanNameAware {
private ApplicationContext applicationContext;
private String beanName;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setBeanName(String name) {
this.beanName = name;
}
public String getBeanName() {
return beanName;
}
}
3、BeanFactoryPostProcessor与BeanPostProcessor
BeanFactoryPostProcessor:在refresh方法的第5步执行(invokeBeanFactoryPostProcessors方法)此时已经创建好了beanFactory,并且加载好了BeanDefinition,可以在这一阶段增强(修改)BeanDefinition属性。
BeanPostProcessor:在refresh方法的第11步执行(finishBeanFactoryInitialization方法),在这一步创建bean实例 -> 属性依赖注入 -> 初始化bean(initializeBean方法)。其中initializeBean方法包括:1、调用Aware接口方法 2、调用BeanPostProcessor.before方法 3、调用init-method方法 4、调用BeanPostProcessor.after方法 可以在这一阶段增强(修改)Bean对象属性
查看代码
package beans;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* BeanFactoryPostProcessor 用于增强(修改)BeanDefinition
* 这里把org.springframework包下所有的bean设置了Lazy
*/
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
if (beanDefinitionName.startsWith("org.springframework")) {
continue;
}
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName);
beanDefinition.setLazyInit(true);
}
}
}
查看代码
package beans;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* BeanPostProcessor用法
*
* 每个bean实例化之后,都会触发该方法。用于增强(修改)bean对象
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("[BeanPostProcessor] 后置处理 " + beanName);
if (bean instanceof User) {
System.out.println(String.format("[BeanPostProcessor] 在bean初始化之后 init方法之前 beanName %s bean实例 %s 修改为 %s",
beanName, bean, "Before修改的值"));
User user = (User) bean;
user.setName("Before修改的值");
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof User) {
System.out.println(String.format("[BeanPostProcessor] 在bean初始化之后 init方法之后 beanName %s bean实例 %s 修改为 %s",
beanName, bean, "After修改的值"));
User user = (User) bean;
user.setName("After修改的值");
}
return bean;
}
}
4、beanFactory与factoryBean区别?
1)都是用来创建对象的
2)使用beanFactory时,必须要遵循完整的创建过程,这个过程是由spring来控制的
3)当使用factoryBean只需要调用getObject()可以返回具体的对象,对象的创建过程由自己来控制,更加灵活
查看代码
package beans;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
/**
* 可以自定义FactoryBean来创建bean对象,避开beanFactory的创建过程
*
* 获取bean
* Object user = ctx.getBean("userFactoryBean");
* System.out.println(user);
*
* 获取FactoryBean
* Object userFactoryBean = ctx.getBean("&userFactoryBean");
* System.out.println(userFactoryBean);
*/
@Component
public class UserFactoryBean implements FactoryBean<User> {
@Override
public User getObject() throws Exception {
return new User();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}
5、父子容器概念
Spring是SpringMVC父容器,SpringMVC可以获取Spring配置的bean,反之不行。
6、循环依赖针对单例bean和原型bean会发生什么
单例bean发生循环依赖,Spring会使用三级缓存来解决。原型bean发生循环依赖,会直接报异常。