Spring IOC、AOP实现源码分析

以下分析基于spring-framework-5.0.x相关源码可自行去github下载或者maven依赖然后利用类似ideal工具自动关联源码功能。

what is IOC

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)
spring实现IOC的思路是提供一些配置信息用来描述类之间的依赖关系,然后由容器去解析这些配置信息,继而维护好对象之间的依赖关系,前提是对象之间的依赖关系必须在类中定义好,比如A.class中有一个B.class的属性,那么我们可以理解为A依赖了B。
spring实现IOC的思路大致可以拆分成3点:

  • 应用程序中提供类,提供依赖关系(属性或者构造方法)
  • 把需要交给容器管理的对象通过配置信息告诉容器(xml、annotation,javaconfig)
  • 把各个类之间的依赖关系通过配置信息告诉容器(如果使用自动装配这一步可以不用)

配置这些信息的方法有三种分别是xml,annotation和javaconfig
维护的过程称为自动注入,自动注入的方法有两种构造方法和setter
自动注入的值可以是对象,数组,map,list和常量比如字符串整形等
spring编程的风格:

  • schemal-based-------xml
  • annotation-based-----annotation
  • java-based----java Configuration

自动装配
上面说过,IOC的注入有两个地方需要提供依赖关系,一是类的定义中,二是在spring的配置中需要去描述。自动装配则把第二个取消了,即我们仅仅需要在类中提供依赖,继而把对象交给容器管理即可完成注入。
在实际开发中,描述类之间的依赖关系通常是大篇幅的,如果使用自动装配则省去了很多配置,并且如果对象的依赖发生更新我们可以不需要去更新配置,但是也带来了一定的缺点
IOC自动注入(不需要提供set方法),可以通过xml配置default-autowire="byType" (可选no、constructor(与byType的方式类似,不同之处在于它应用于构造器参数)、byName(根据属性名注入与set方法无关)、byType(在bean工厂中查询set方法对应的类型,与属性无关)) ,也可以单独对某个bean设置装配类型,只需在对应的标签中设置即可。 当使用注解@Autowire时优先使用属性对应的类注入(与set无关),如果没找到合适的(包括找到不少于两个bean时)再根据属性名再次查找。

Bean实例化
在@Bean注解标志的beanDefinition实例化时会采用factoryMethod构造实现,因为它注册bdmap(底层是concurrentMap)时,设置了FactoryMethodName。

//设置FactoryMethodName
ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(){
...if (metadata.isStatic()) {
			// static @Bean method
			beanDef.setBeanClassName(configClass.getMetadata().getClassName());
			beanDef.setFactoryMethodName(methodName);
		}
		else {
			// instance @Bean method
			beanDef.setFactoryBeanName(configClass.getBeanName());
			beanDef.setUniqueFactoryMethodName(methodName);
		}
...
}
//bean实例化
AbstractAutowireCapableBeanFactory.createBeanInstance(){
...if (mbd.getFactoryMethodName() != null)  {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}
...
                //当bean使用默认的无参构造方法进行初始化时
		return instantiateBean(beanName, mbd);
...
}
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
...
else {
	//getInstantiationStrategy()得到类的实例化策略 默认情况下是得到一个反射的实例化策略
	beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
	}
	BeanWrapper bw = new BeanWrapperImpl(beanInstance);
	initBeanWrapper(bw);
	return bw;//返回
...
}
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides. 检测 bean 配置中是否配置了 lookup-method 或 replace-method 如果配置了就需使用 CGLIB 构建 bean 对象
	if (!bd.hasMethodOverrides()) {
		...
		    if (System.getSecurityManager() != null) {
			constructorToUse = AccessController.doPrivileged(
			(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
			}
			else {
				constructorToUse =clazz.getDeclaredConstructor();//通过反射获取构造方法
			}
			bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                        ... return BeanUtils.instantiateClass(constructorToUse);//实例化
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
...
}
instantiateClass(){
    ... return ctor.newInstance(argsWithDefaultValues); ...
}

AOP实现

//首先注入相关的BeanPostProcessor 后置处理器
@EnableAspectJAutoProxy->@Import(AspectJAutoProxyRegistrar.class)
AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
...
@Override
public void registerBeanDefinitions(
	AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        //最终注册了AnnotationAwareAspectJAutoProxyCreator(父类AbstractAutoProxyCreator 层层继承最终extends BeanPostProcessor )bean 下面@one标志处会执行这个BeanPostProcessor 的postProcessAfterInitialization
	AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry)->return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    }
...
}

//实例化bean时织入Aop
AbstractAutowireCapableBeanFactory.doCreateBean(){
...
    //设置属性,非常重要
    populateBean(beanName, mbd, instanceWrapper);
    //执行后置处理器,aop就是在这里完成的处理
    exposedObject = initializeBean(beanName, exposedObject, mbd);
...
}
initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
...
	//执行后置处理的befor
	wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	...
	invokeInitMethods(beanName, wrappedBean, mbd);
	...
	//执行后置处理器的after方法
	wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);	
}
@Override
applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {
    ...
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
	Object current = processor.postProcessAfterInitialization(result, beanName);//@one
	if (current == null) {
		return result;
	}
	result = current;
    }
    return r
}
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
	...
	return wrapIfNecessary(bean, beanName, cacheKey);
        return bean;
}

wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	...
        // Create proxy if we have advice.符合织面的就创建代理
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}
	...
}
createProxy(...) {
...
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);
    return proxyFactory.getProxy(getProxyClassLoader());//再往下就是jdk代理和cglib代理了自行看
...
}

参考文档:
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-lifecycle

posted @ 2020-04-15 16:00  gsluofu  阅读(349)  评论(0编辑  收藏  举报