一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情。
- 先得找到需要初始化的Bean
- 对Bean创建对象(调用构造方法)
- 创建对象需要对标注的属性赋值
- Spring对这个对象进行一些初始化操作,让他达到满足放入Spring池中的要求
- 放入Map这个单例池中
- 使用这个Bean
- 不用了,以后也不用了就销毁这个Bean
构造->依赖注入->初始化->使用->销毁
@Component
public class UserService{
@Autowried
public UserMapper userMapper;
public void test(){
System.out.Println("我是test")
}
}
@ComponentScan->@Component->无参构造方法->对象实例
构造
构造:项目的启动类上面直接或间接的有@ComponentScan
注解,表示要扫描包里面的@Component
注解,扫描到了@Component注解。想要创建一个对象
创建对象的方法只有两种
- 使用类的构造方法
- 反射创建
所以这个地方就使用了类的默认都会有的无参构造创建了UserService
的bean
实例对象userService
依赖注入
对象实例->依赖注入->找这个bean实例上面加了@Autowired
/xxx/xxx的注解->
依赖注入:找这个bean实例上加了@Autowried
之类的一些注解。然后给这个bean实例的这个属性进行赋值。赋值来源就来源于Spring池中,先试用类进行获取,获取之后如果有多个就会再使用属性值进行获取。比如private UserService userService
先去找UserService这个类,找到多个就找userService这个值对应的Bean对象
初始化
初始化:使用后处理器对这个bean进行一些设置;如果是单例将这个Bean实例对象放入Spring单例池中的Map<String,Object>中。之类的一些操作
包括一些自定义的操作,比如UserService中我想要在创建bean的时候就知道管理员的一些基本信息,也就是我有一个属性是User admin
;然后这个数据需要从数据库中获取。 也就是userService默认带有一个动态的管理员信息
初始化前:@PostConstruct
注解标注的方法会在初始化前进行执行,其中需要的参数会在SpringBean池中获取
初始化中:实现InitializingBean
接口中的方法,可以做到在这个bean
的初始化中进行执行该方法的方法体逻辑
初始化后:将AOP的切面注册到这个Bean的切点中。如果有切点,就会生成代理对象。并将这个代理对象注入到Bean池中
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// System.getSecurityManager()安全管理:因为下面初始化bean的时候会运行一些用户自定义的一些方法(实现BeanNameAware , BeanFactoryAware, BeanClassLoaderAware接口的方法)
// Spring并不能保证这些方法会做一些违规操作,比如(删除系统文件、重启系统等)为了防止运行恶意代码对系统产生影响,需要对运行的代码的权限进行控制,这时候就要启用Java安全管理器。
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// 对实现了 BeanNameAware , BeanFactoryAware, BeanClassLoaderAware的Bean进行处理
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//应用Bean的后处理器在初始化前
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//应用初始化方法(包括自定义的初始化方法)
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//应用后处理器在初始化结束的时候
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
处理继承了Aware接口的Bean的一些方法invokeAwareMethods
/**
* 处理继承Aware的bean的一些操作
* Aware有很多子接口,这些接口拥有一种感知能力,把你想要的对象注入到你的类中
* 如果实现了BeanNameAware,则会有一个方法setBeanName,在方法里面可以自定义一些操作。然后这个地方就有调用这个方法。
* 如果实现了BeanClassLoaderAware,就会调用setBeanClassLoader方法
* 如果实现了BeanFactoryAware,就会调用setBeanFactory方法。
* 区别在于参数不一样,具体的方法所能实现的功能也不一样
* @param beanName
* @param bean
*/
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);
}
}
}
class A implements BeanNameAware , BeanFactoryAware, BeanClassLoaderAware {
@Override
public void setBeanName(String name) {
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
}
}
处理该工厂使用的后处理器作用在该bean上applyBeanPostProcessorsBeforeInitialization
/**
* 在Bean的初始化前使用Bean的后处理器
* 遍历使用此工厂创建的 bean 的 BeanPostProcessor 列表。对该bean进行应用这些后处理器
* @param existingBean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
按照用户自定义的规则开始初始化这个 BeaninvokeInitMethods
/**
* 应用用户自定义的规则进行初始化这个Bean
* 如果自定义?
* 1、实现InitializingBean接口的afterPropertiesSet方法
* 2、该bean的RootBeanDefinition 中initMethod 方法
*/
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
//1、判断是否实现了InitializingBean接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
//获取这个Bean的初始化方法。然后去执行他的invokeCustomInitMethod方法去调用初始化方法
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
初始化总结:初始化的时候Spring干了几件事
1、处理实现了BeanNameAware , BeanFactoryAware, BeanClassLoaderAware的Bean的方法
2、在初始化前调用这个工厂配置的后处理器
3、调用用户自定义的初始化方法(InitializingBean接口、RootBeanDefinition 中initMethod 方法)
4、在初始化结束调用这个工厂配置的后处理器