八股文_常规_spring

162 阅读4分钟
Bean生命周期

BeanFactory这个类的注释上写了Bean生命周期中执行的方法顺序

  • 解析类得到BeanDefinition
  • 使用BeanFactoryPostProcessor对BeanDefinition进行增强,如把${}占位符换成具体的值
  • 创建对象,填充属性
  • 回调Aware方法,比如BeanNameAwareBeanFactoryAware
  • 调用BeanPostProcessorbefore()
  • 调用InitializingBean.afterPropertiesSet()
  • 调用BeanPostProcessorafter()(此处进行AOP)
  • 把Bean放入map中
  • 容器关闭时调用DisposableBeandestory()方法

Snipaste\_2024-11-11\_16-19-04.jpg

Snipaste_2024-11-03_23-48-33.jpg

Bean创建过程中的方法
  • getBean()
  • doGetBean()
  • getSingleton()
  • createBean()
  • doCreateBean()
  • createBeanInstance()
  • populateBean()
  • initializeBean()
AOP切面

生成一个bean对象的代理对象,对原来的bean进行前置增强,后置增强等,并将代理对象放入容器中,spring使用的是jdk代理,springboot是cglib代理

循环依赖处理过程
  • Spring首先把创建bean对象的工厂放入三级缓存
  • 当发生循环依赖时,会先从三级缓存中拿到创建该bean对象的bean工厂,然后生成bean的代理对象,并放入二级缓存中,进行提前暴露
  • 最后所有的bean初始化完会放入一级缓存
三级缓存
  • 三级缓存:存储创建bean的工厂对象(函数式接口)
  • 二级缓存:存储已经创建但未完全初始化的对象,避免循环依赖
  • 一级缓存:存储完全初始化的对象
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    Object exposedObject = bean;
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
            exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
        }
    }
    return exposedObject;
}

Snipaste_2024-11-14_11-32-28.jpg

1.jpg

Aware接口的作用

Aware接口用来获取容器中的某些对象。在Bean初始化过程中,会调用Aware接口的实现方法,spring会将相应的参数传入进去,如beanName、applicationContext、environment,可以借此拿到相应对象,当事务发生内部回调时,可以通过拿到容器对象来避免事务不执行

@Data
@Service
public class UserService implements ApplicationContextAware {
    private ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }

    public void test() {
        UserService userService = (UserService) context.getBean("userService");
        System.out.println("ok");
    }
}

源码: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);
			}
		}
	}
FactoryBean的作用

这个接口里面有一个T getObject()方法,从容器中取对象的时候,最后实际得到的对象是getObject方法返回的结果。可以用来创建复杂的对象,比如通过加载配置文件才能实例化对象

public class UserService implements FactoryBean<Object> {
    public Object getObject() throws Exception {
        return new Date();
    }

    public Class<?> getObjectType() {
        return Date.class;
    }
}
BeanFactoryPostProcessor和BeanPostProcessor区别
  • BeanPostProcessor:处理Bean属性,在InitializingBean初始化对象前后进行处理,如进行AOP生成代理对象AbstractAdvisorAutoProxyCreator

  • BeanFactoryPostProcessor:处理BeanDefinition属性,如处理占位符PlaceholderConfigurerSupport

    public class DkBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            //获取coder的BeanDefinition对象
            BeanDefinition coder = beanFactory.getBeanDefinition("coder");
            //修改其class
            coder.setBeanClassName(Manager.class.getName());
        }
    }
    
涉及的设计模式
  • 单例模式 : Spring 中的 Bean 默认都是单例的
  • 代理模式 : Spring AOP 功能的实现
  • 责任链模式:SpringMvc中的拦截器,多个拦截器串联起来就形成了责任链
SpringBoot中的starter

在starter中会定义相应的AutoConfiguration,如RedisAutoConfiguration,MybatisAutoConfiguration,在这些configuration中就定义了要用到的第三方Bean对象,然后在 starter包的META-INF/spring.factories中写入该配置类,SpringBoot的自动配置机制加载这个配置类,完成自动配置

SpringMVC工作流程

mvc架构.jpg

  • 用户发送请求到DispatcherServlet

  • 执行拦截器的前置处理方法preHandle(),如果返回false,请求处理中止

  • DispatcherServlet通过HandlerMapping找到能够处理这个请求的Handler(比如处理静态资源的ResourceHttpRequestHandlerHandlerMethod)

  • 执行控制器中的业务逻辑

  • 执行后置拦截器postHandle()

  • 如果返回的是视图,进行视图解析和渲染,如果返回的是对象,将对象转换成json

  • 视图渲染或json解析完后,调用拦截器的afterCompletion()方法

  • 响应客户端

过滤器和拦截器的区别
  • 过滤器是servlet包中提供的接口,拦截器是springmvc中提供的

  • 过滤器执行的时间更早

  • 拦截器中可以访问控制器中返回的数据模型,过滤器不可以

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView){
        if(modelAndView != null) {
            Object message = modelAndView.getModel().get("message");
            Object user = modelAndView.getModel().get("user");
        }
    }
    

640.png

640 (1).png