以下分析基于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设置装配类型,只需在对应的
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代理了自行看
...
}