Spring源码学习

概念
  1. 自动注入:配置的类属性按类型装配,没找到,属性为null, default-autowire=“byType”
    如果一个类中的属性,并且提供了这个属性的set方法,通过这个类的属性的类型去容器中去找,
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd" default-autowire="byType">
	<bean id="zlService" class="com.zfx.service.ZLService"/>
	<bean id="lbService" class="com.zfx.service.LubanService"/>
</beans>
  1. bean初始化流程
    AnnotationConfigApplicationContext -> refresh() -> finishBeanFactoryInitialization(beanFactory) ->beanFactory.preInstantiateSingletons() ->getBean(beanName) ->doGetBean -> createBean -> doCreateBean-> populateBean(设置属性)
  2. 动态代理的原理
  3. BeanDefinition extends AttributeAccessor, BeanMetadataElement
    BeanDefinition : 描述类的元信息
    AttributeAccessor: 对类的原信息没有的属性进行扩展
    BeanMetadataElement:描述该类在磁盘上的Java文件的位置信息
经典面试题
  • 手动装配 @Autowired,XML中 ref 指定
    ① @Autowired, 先按名称在容器中查找注入,若找不到再按类型查找,在找不到,报错。
  • spring注入方式有几种?
    ① set 注入
    ② 构造方法注入
    spring的自动注入模型有几种? Autowiring modes,官方1.4.5
  • spring 怎么体现默认支持循环依赖
    ① 单例,不能用构造方法注入,可以关闭循环依赖
  • Spring中运用了哪些策略模式?
    ① bean工厂模式
    ② 策略模式: 在beanFactory的后置处理器,和 bean的后置处理器中使用(在完成bean的属性注入后,使用不同的后置处理器,)
    ![(https://img-blog.csdnimg.cn/20200605155802255.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyMjIzNTY1,size_12,color_FFFFFF,t_70))

在这里插入图片描述

/*
	验证单例模式, 关闭循环依赖 异常信息:Error creating bean with name 'orderService': Requested bean is currently in creation: Is there an unresolvable circular reference?
 */
	@Test
	public void t7(){
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
		ac.register(AppConfig.class);
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) ac.getBeanFactory();
		beanFactory.setAllowCircularReferences(false); //禁止循环注入
		ac.refresh();
	}

```java
	// 判断是否允许 循环依赖  this.allowCircularReferences 属性默认为 true(类:AbstractAutowireCapableBeanFactory)
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));

``

Model描述
no没有使用自动注入
byName按名称查找注入
byType按类型查找注入
constructor推断构造方法注入,若构造方法存在多个时,使用构造方法属性在容器中存在的个数最多的一个构造方法
  • Spring容器加载完成后,回调方法初始化方式
方式描述
InitializingBean实现该interface,实现afterPropertiesSet()方法
@PostConstruct使用该注解
init-method=“init”bean标签上配置

注:若三种同时配置到一个bean上,优先级生效顺序如下:
注解> 实现接口 > xml中配置

  • FactoryBean和普通的bean有什么区别

  • 如何把一个对象放入到spring容器当中
    ① ac.getBeanFactory().registerSingleton();
    ② implements FactoryBean

  • BeanFactoryPostProcessor —bean 工厂的后置处理器 干预bean工厂的实例化过程

  • Spring AOP 包含哪些通知类型
    ① Before advice
    ② After returning advice
    ③ After throwing advice
    ④ After (finally) advice
    ⑤ Around advice

  • AOP是什么
    定义:与OOP相比,面向切面,传统的OOP开发中的代码逻辑是自上而下的,而这些过程会产生一些横切性的问题,这些横切性的问题与我们的主业务逻辑关系不大,这些横切性问题不会影响到主业务逻辑的实现,但是会散落到代码的各个部分,难以维护,AOP是处理一些横切性问题,AOP的编程思想就是把这些问题和主业务逻辑分开,达到与主业务逻辑解耦的目的,使代码的重用性和开发效率提高。

  • AOP的应用场景
    ① 日志记录
    ② 权限验证
    ③ 效率检测
    ④ 事务管理
    ⑤ exception

  • Spring中如何选择Cglib 和 jdk动态代理的

@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			Class<?> targetClass = config.getTargetClass();
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config); //使用jdk代理
			}
			return new ObjenesisCglibAopProxy(config); // 使用CGLIB 代理
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

① 当bean实现接口时,会用JDK代理模式,当bean没有实现接口,用cglib实现
② 可以强制指定使用哪种 <aop:aspectj-autoproxy proxyt-target-class=”true”/> 或者 proxyTargetClass = true, true表示强制使用cglib

  • Spring 通过构造方法实例bean 的原理?
    ① 首先实例化这个对象
    ② 推断构造方法
    • 手动注入:调用 determineConstructorsFromBeanPostProcessors 方法第一次推断构造方法,分几种情况, 如果没有构造方法----- 该方法返回为Null,用默认的无参构造
      1.1 如果提供了默认的构造方法只有这一个 ---- 为null ---- 使用默认的
      1.2 如果提供了多个构造方法,— 该方法返回null,— 迷茫 ---- 使用默认的构造方法
      1.3 如果提供了多个构造方法,且指定为 @Autowired(required = true), 异常, 不知道该选哪个
      1.4 如果提供了多个构造方法,且指定为@Autowired(required = false),表示使用这几个都有可能用,则返回多个,— 进行再次的 B推断----
      1.5 提供了一个构造方法且不是默认的构造— 返回1个,用这个提供的构造方法
    • 自动注入(推断B):推断出一个最优的构造方法 , 获取该构造方法中 有效的参数值 个数最多的一个构造方法。 若提供的构造方法参数个数一致(提供了多个模糊的构造方法),(即通过算法计算构造方法的参数差异值一样),判断系统配置的 是否采用严禁的构造,默认是宽松的。宽松的选其中一个,严禁的话直接报异常。

后置处理器

  • bean 工厂的后置处理器 BeanDefinitionRegistryPostProcessor
    ① 首先执行程序员通过API提供的 ac.addBeanFactoryPostProcessor(new LuBanFactoryPostprocessor());
    ② 然后执行spring内置的----- 程序员提供的---- 有特点的 impl PriorityOrdered.class
    ③ 再执行程序员提供的 — 没有任何特点的 X impl BeanDefinitionRegistryPostProcessor ---- postProcessBeanDefinitionRegistry()
  • bean 的后置处理器
    ① 执行的是 X impl BeanDefinitionRegistryPostProcessor postProcessBeanFactory()
    ② 执行的是 BeanFactoryPostProcessor postProcessBeanFactory()

CGLib

Spring循环依赖

spring可以解决循环依赖的条件: 单例 并且是 setter 注入

  1. 推断构造方法
  2. 实例化一个对象
  3. 属性注入
  4. 声明周期回调初始化方法
  5. aop代理
  6. 三级缓存
    ① singletonObject cache1
    ② singletonFactories cache2
    ③ earlySingletonObjects cache3
Bean的后置处理器置入位置
0 = {ApplicationContextAwareProcessor@1878}refresh() ->prepareBeanFactory()-> beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this))
1 = {ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@1879}
2 = {PostProcessorRegistrationDelegate$BeanPostProcessorChecker@1880}refresh() -> registerBeanPostProcessors(beanFactory)()-> registerBeanPostProcessors-> beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount))
3 = {CommonAnnotationBeanPostProcessor@1881}
4 = {AutowiredAnnotationBeanPostProcessor@1882}@EnableAspectJAutoProxy ->@Import(AspectJAutoProxyRegistrar.class) -> registerOrEscalateApcAsRequiredAopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry)
5 = {RequiredAnnotationBeanPostProcessor@1883}
6 = {ApplicationListenerDetector@1884}refresh() ->prepareBeanFactory()-> beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this))

Spring AOP

  1. aspect 切面
    • Join point 连接点,aop-代理— 增强对象\类— 一个方法
    • advice 通知
    • pointCut 切入点 — 某一类型连接点的集合
    • target 目标对象
    • proxy 代理对象
    • weaving 织入
  2. bean 的生命周期 bd -> class -> object -> bean
    • 判断当前Bean 是不是需要被代理
    • 拿到这个类,判断这个类是否满足@PointCut 指定的表达式

构造方法推断 与注入的模型有关

  • 手动装配,默认@AutoWired
    ① 提供两个有效的,异常 构造方法上加 @AutoWired 指定使用这个构造方法实例化
    ② 提供1个,不是有效的,就会推断出来
    ③ 提供多个构造(包括无参的),默认使用无参的
    ④ 提供多个构造(不包括无参的),异常:ested exception is java.lang.NoSuchMethodException: com.zfx.service.OrderService.
  • 自动装配: mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR
    ① 全部拿出来,推断使用哪一个构造
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值