zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    简单组网(根据MAC地址划分VLAN)
    简单组网(根据接口划分VLAN)
    简单组网(LACP)负载分担链路聚合
    简单组网(Eth-Trunk)负载分担链路聚合
    《数字图像处理_第三版_中_冈萨雷斯》第一章笔记
    安全测试类型
    全链路压测
    容量测试与容量规划
    性能测试详细介绍
    树莓派vnc连接,放歌调节声音
  • 原文地址:https://www.cnblogs.com/leifonlyone/p/12705949.html
Copyright © 2011-2022 走看看