Spring框架

一、Spring框架设计

Spring framework 6大模块

1.1 Spring AOP

AOP: 面向切面编程

Spring 早期版本的核心功能,管理对象声明周期和对象装配

为了实现管理和装配,一个自然的想法就是,加一个中间层代理(字节码增强)来实现所有对象的托管

IoC:控制反转

IoC是一个宽泛的概念,而DI(依赖注入)是其中的一种实现方式。

从对象A直接引入和操作对象B,变成对象A只需要依赖一个接口IB,系统启动和装配阶段,把IB接口的实例对象注入到对象A,这样A就不需要依赖一个IB接口的具体实现。

从而达到修改配置文件,就可以在运行时替换成注入IB接口的其他实现类的一个对象实例。

思考:Spring怎么解决循环依赖?

当实例A依赖B,实例B依赖A时。就构成了循环依赖。Spring解决的思路就是先构造一个"早期"对象,对象的属性还没填充,然后将这个早期对象注入容器。让B完成实例化,此时A就能获取到B的引用,完成了实例化。

具体实现是通过Spring的三级缓存。

什么类型的循环依赖Spring无法处理?

答:双方都是构造函数注入或主bean对象(Spring启动中先加载的对象)使用构造函数注入。

构造器注入和setter注入在创建bean时候的区别

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	///隐藏无用代码
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				return instantiateBean(beanName, mbd);
			}
		}

	    //获取构造器注入
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction?
		ctors = mbd.getPreferredConstructors();
		//如果ctors不为空,就是构造器注入
		if (ctors != null) {
			return
			//需要去创建构造器里依赖的bean,此时还没实例化出对象来放入三级缓存
			autowireConstructor(beanName, mbd, ctors, null);
		}

		//不是构造器注入,就可以实例化出一个bean来,并放入三级缓存里面了。
		return instantiateBean(beanName, mbd);
	}

Spring AOP的实现方式:

动态代理

接口类型,默认使用JDK动态代理。非接口类型默认使用CGlib。

如果接口类型想改为用CBlib动态代理:

spring xml:

<aop:aspectj-autoproxy  expose-proxy="true"    proxy-target-class="true"/>

spring boot 配置文件:

# 增加@EnableAspectJAutoProxy
spring.aop.auto=true
# 开启CGLIB代理
spring.aop.proxy-target-class=true

字节码增强

1.2 Spring Bean

Bean的加载过程:

  1. 创建对象
  2. 属性赋值
  3. 初始化
  4. 注销接口注册
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
		// 1. 实例化bean
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

        /**
        省略部分代码
        **/

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
		    //2.属性赋值
			populateBean(beanName, mbd, instanceWrapper);
			//3.初始化
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

	/**
	省略部分代码
	**/

		// 4.销毁的回调方法
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

Bean的初始化过程:

  1. 检查Aware装配
  2. BeanPostProcessors前置处理
  3. init方法
  4. BeanPostProcessors后置处理
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        //1.检查Aware接口并设置相关依赖
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
		    //2.BeanPostProcessor前置处理
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
		    //若有init方法,则执行
		    //若实现了InitializingBean接口,则执行
			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()) {
		    //BeanPostProcessor后置方法处理
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
posted @ 2021-06-10 22:58  女友在高考  阅读(128)  评论(0编辑  收藏  举报