# OZAnnoIocDemo **Repository Path**: orangezh/OZAnnoIocDemo ## Basic Information - **Project Name**: OZAnnoIocDemo - **Description**: 实现简单的Spring的Ioc容器,包含容器初始化,Bean实例化,实现@Service、@Autowired、@Transactional、@Bean、@Value等注解 - **Primary Language**: Java - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 2 - **Created**: 2020-09-12 - **Last Updated**: 2022-07-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OZAnnoIocDemo #### 介绍 实现简单的Spring的Ioc容器,包含容器初始化,Bean实例化,实现@Service、@Autowired、@Transactional、@Bean、@Value等注解 #### 什么是IOC IoC Inversion of Control (控制反转/反转控制),它是⼀个技术思想,不是⼀个技术实现 描述的事情:Java开发领域对象的创建,管理的问题 传统开发⽅式:⽐如类A依赖于类B,往往会在类A中new⼀个B的对象 IoC思想下开发⽅式:我们不⽤⾃⼰去new对象了,⽽是由IoC容器(Spring框架)去帮助我们实例化对象并且管理它,我们需要使⽤哪个对象,去问IoC容器要即可 我们丧失了⼀个权利(创建、管理对象的权利),得到了⼀个福利(不⽤考虑对象的创建、管理等⼀系列事情) 为什么叫做控制反转? 控制:指的是对象创建(实例化、管理)的权利 反转:控制权交给外部环境了(spring框架、IoC容器) IoC解决对象之间的耦合问题 IOC和DI描述的是同⼀件事情,只不过⻆度不⼀样

IOC容器示例
#### 什么是AOP AOP: Aspect oriented Programming ⾯向切⾯编程/⾯向⽅⾯编程 AOP是OOP的延续,从OOP说起 OOP三⼤特征:封装、继承和多态 OOP是⼀种垂直继承体系,而AOP是一种纵向的体系 比如:想在多个业务方法运行前后记录日志,为了不影响业务代码那么就抽象出一个横切逻辑单读维护 #### 手写实现IOC和AOP 案例实现了IOC容器的管理,包含容器初始化,Bean实例化,实现@Service、@Autowired、@Transactional、@Bean、@Value等注解,其中@Transactional就属于AOP的一种实现(动态代理) - 导入必要的依赖包 ``` junit junit 4.12 mysql mysql-connector-java 8.0.21 com.alibaba druid 1.1.21 javax.servlet javax.servlet-api 3.1.0 provided com.fasterxml.jackson.core jackson-databind 2.9.6 dom4j dom4j 1.6.1 jaxen jaxen 1.1.6 cglib cglib 2.1_2 ``` - 创建数据库外部配置文件 jdbc.properties ``` jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ozdemo?characterEncoding=utf-8 jdbc.username=root jdbc.password=123456 ``` - 创建数据库表 ``` SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for account -- ---------------------------- DROP TABLE IF EXISTS `account`; CREATE TABLE `account` ( `aid` int(11) NOT NULL AUTO_INCREMENT, `cardNo` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `money` int(11) NOT NULL DEFAULT 0, PRIMARY KEY (`aid`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of account -- ---------------------------- INSERT INTO `account` VALUES (1, '6029621011001', '韩梅梅', 10000); INSERT INTO `account` VALUES (2, '6029621011000', '李大雷', 10000); SET FOREIGN_KEY_CHECKS = 1; ``` - 创建必要的注解类 @Service、@Autowired、@Transactional、@Bean、@Value、@Component等 @Transactional示例:其它类似 ``` /** * @Description: @Transactional注解 * @Author: Created by OrangeZh * @Date: Created in 2020/9/4 17:37 */ @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Transactional { String value() default ""; String transactionManager() default ""; } ``` - **(AOP关建代码)创建动态代理工厂类 ProxyFactory和事务类 TransactionManager** ``` /** * 代理对象工厂:生成代理对象的 */ @Component("proxyFactory") public class ProxyFactory { @Autowired private TransactionManager transactionManager; /** * Jdk动态代理 * * @param obj 委托对象 * @return 代理对象 */ public Object getJdkProxy(Object obj) { // 获取代理对象 return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try { // 开启事务(关闭事务的自动提交) transactionManager.beginTransaction(); result = method.invoke(obj, args); // 提交事务 transactionManager.commit(); } catch (Exception e) { e.printStackTrace(); // 回滚事务 transactionManager.rollback(); // 抛出异常便于上层servlet捕获 throw e; } return result; } }); } /** * 使用cglib动态代理生成代理对象 * * @param obj 委托对象 * @return */ public Object getCglibProxy(Object obj) { return Enhancer.create(obj.getClass(), new MethodInterceptor() { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { Object result = null; try { // 开启事务(关闭事务的自动提交) transactionManager.beginTransaction(); result = method.invoke(obj, objects); // 提交事务 transactionManager.commit(); } catch (Exception e) { e.printStackTrace(); // 回滚事务 transactionManager.rollback(); // 抛出异常便于上层servlet捕获 throw e; } return result; } }); } } /** * 事务管理器类:负责手动事务的开启、提交、回滚 */ @Component("transactionManager") public class TransactionManager { @Autowired private ConnectionUtils connectionUtils; // 开启手动事务控制 public void beginTransaction() throws SQLException { connectionUtils.getCurrentThreadConn().setAutoCommit(false); } // 提交事务 public void commit() throws SQLException { connectionUtils.getCurrentThreadConn().commit(); } // 回滚事务 public void rollback() throws SQLException { connectionUtils.getCurrentThreadConn().rollback(); } } ``` - **(IOC关建代码)创建BeanFactory IOC容器 bean工厂** ``` /** * @Description: IOC容器 bean工厂 * @Author: Created by OrangeZh * @Date: Created in 2020/9/4 15:15 */ public class BeanFactory { //外部配置文件配置信息 private static Properties properties = new Properties(); private static final String classpath = BeanFactory.class.getResource("/").getPath(); //bean定义Map 处理存放bean的基本信息 private static Map> beanDefinitionMap = new ConcurrentHashMap<>(); //缓存bean 容器缓存(单例缓存池) private static ConcurrentHashMap beanMap = new ConcurrentHashMap<>(); //扫描到的所有类 private static List> classList = new ArrayList<>(); static { initIoc(); } /** * 初始化容器 * 1、获取配置文件配置内容 * 2、配置类(AppConfig)解析 * 3、扫描包下的所有类 * 4、遍历所有类,并放入到beanDefinitionMap中 * 5、实例化并初始化所有bean */ private static void initIoc() { try { //1、获取配置文件配置内容 properties = getProperties("jdbc.properties"); //2、配置类解析 Class configClass = AppConfig.class; String configBeanName = Introspector.decapitalize(configClass.getSimpleName()); beanDefinitionMap.put(configBeanName, configClass); String[] scanPackages = configClass.getAnnotation(ComponentScan.class).value(); //3、加载包下的所有类 if (scanPackages.length > 0) { for (String scanPackage : scanPackages) { getAllClasses(scanPackage, classList); } } else { getAllClasses("", classList); } //4、遍历所有类,并放入到beanDefinitionMap中 if (classList.size() > 0) { for (Class clazz : classList) { String beanName = Introspector.decapitalize(clazz.getSimpleName()); //类注解 if (clazz.isAnnotationPresent(Component.class)) { Component annotation = clazz.getAnnotation(Component.class); if (!annotation.value().equals("")) { beanName = annotation.value(); } else if (clazz.getInterfaces().length > 0) { beanName = Introspector.decapitalize(clazz.getInterfaces()[0].getSimpleName()); } } else if (clazz.isAnnotationPresent(Service.class)) { Service annotation = clazz.getAnnotation(Service.class); if (!annotation.value().equals("")) { beanName = annotation.value(); } else if (clazz.getInterfaces().length > 0) { beanName = Introspector.decapitalize(clazz.getInterfaces()[0].getSimpleName()); } } else if (clazz.isAnnotationPresent(Repository.class)) { Repository annotation = clazz.getAnnotation(Repository.class); if (!annotation.value().equals("")) { beanName = annotation.value(); } } else { continue; } beanDefinitionMap.put(beanName, clazz); } } //5、实例化并初始化所有bean //先初始化配置类 getBean(configBeanName); for (String beanName : beanDefinitionMap.keySet()) { getBean(beanName); } } catch (Exception e) { e.printStackTrace(); } } /** * 创建bean * 1、实例化Bean * 2、初始化Bean * * @param beanName * @throws Exception */ private static Object doCreateBean(String beanName) throws Exception { Object bean = beanMap.get(beanName); if (bean != null) { return bean; } createBeanInstance(beanName); populateBean(beanName); return beanMap.get(beanName); } /** * 实例化Bean * * @param beanName * @throws Exception */ private static void createBeanInstance(String beanName) throws Exception { Class clazz = beanDefinitionMap.get(beanName); //实例化 Object bean = clazz.newInstance(); if (clazz.isAnnotationPresent(Transactional.class)) { //转为代理对象 ProxyFactory proxyFactory = (ProxyFactory) getBean("proxyFactory"); if (clazz.getInterfaces().length > 0) { bean = proxyFactory.getJdkProxy(bean);//代理对象替换原对象 } else { bean = proxyFactory.getCglibProxy(bean);//代理对象替换原对象 } } beanMap.put(beanName, bean); } /** * 初始化Bean * 解析 @Autowired、@Value、@Transactional等注解 * * @param beanName */ private static void populateBean(String beanName) throws Exception { Object bean = getBean(beanName); Class clazz = bean.getClass(); //自动注入 Field[] declaredFields = clazz.getDeclaredFields(); for (Field field : declaredFields) { Annotation[] annotations = field.getAnnotations(); for (Annotation annotation : annotations) { if (annotation.annotationType().equals(Autowired.class)) { //Autowired autowiredAnno = field.getAnnotation(Autowired.class); //通过属性名称 获取bean Object value = getBean(field.getName()); field.setAccessible(true); //给属性赋值 field.set(bean, value); } else if (annotation.annotationType().equals(Value.class)) { Value valueAnno = field.getAnnotation(Value.class); String value = valueAnno.value(); if (value.startsWith("${") && value.endsWith("}")) { value = properties.getProperty(value.split("\\$\\{")[1].split("}")[0]); } field.setAccessible(true); //给属性赋值 field.set(bean, value); } } } //方法注解 Method[] methods = clazz.getMethods(); for (Method method : methods) { Annotation[] annotations = method.getAnnotations(); for (Annotation annotation : annotations) { if (annotation.annotationType().equals(Transactional.class)) { //转为代理对象 ProxyFactory proxyFactory = (ProxyFactory) getBean("proxyFactory"); Class[] cl = clazz.getInterfaces(); if (clazz.getInterfaces().length > 0) { bean = proxyFactory.getJdkProxy(bean);//代理对象替换原对象 } else { bean = proxyFactory.getCglibProxy(bean);//代理对象替换原对象 } beanMap.put(beanName, bean); } else if (annotation.annotationType().equals(Bean.class)) { Bean beanAnno = method.getAnnotation(Bean.class); Class returnClass = method.getReturnType(); String beanName1 = Introspector.decapitalize(returnClass.getSimpleName()); if (!beanAnno.value().equals("")) { beanName1 = beanAnno.value(); } //获取方法执行返回的对象,返回的就是bean Object beanClass = method.invoke(bean); beanMap.put(beanName1, beanClass); } } } } /** * 获取bean * * @param beanName * @return */ public static Object getBean(String beanName) throws Exception { Object bean = beanMap.get(beanName); if (bean == null) { bean = doCreateBean(beanName); } return bean; } /** * 获取某个包下的所有类 * * @param classes 存放类的list * @param packageName 包名 * @return */ private static void getAllClasses(String packageName, List> classes) { try { //将包名转换为路径 String path = classpath + packageName.replaceAll("\\.", Matcher.quoteReplacement(File.separator)); File file = new File(path); File[] fileList = file.listFiles(); if (null != fileList && fileList.length > 0) { for (File curFile : fileList) { if (curFile.isFile()) { System.out.println("file is:" + curFile); System.out.println(packageName + "." + curFile.getName().split("\\.")[0]); Class aClass = Class.forName(packageName + "." + curFile.getName().split("\\.")[0]); classes.add(aClass); } if (curFile.isDirectory()) { System.out.println("dir is :" + curFile); getAllClasses(packageName + "." + curFile.getName(), classes); } } } } catch (Exception e) { e.printStackTrace(); } } /** * 读取配置文件 * * @return */ private static Properties getProperties(String... files) { Properties properties = new Properties(); try { if (files.length > 0) { for (String file : files) { InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream(file); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8"); properties.load(inputStreamReader); } } } catch (Exception e) { e.printStackTrace(); System.out.println("Get properties is fail!"); } return properties; } ``` - 项目源码 [https://gitee.com/orangezh/OZAnnoIocDemo](https://gitee.com/orangezh/OZAnnoIocDemo) #### Spring源码构建 - 下载源码(github) - 安装gradle 5.6.3(类似于maven) Idea Jdk 8+ - 导⼊(耗费⼀定时间) - 编译⼯程(顺序:core-oxm-context-beans-aspects-aop) `⼯程—>tasks—>compileTestJava` - 运行可能出现的错误:[https://zhuanlan.zhihu.com/p/86606269?from_voters_page=true](https://zhuanlan.zhihu.com/p/86606269?from_voters_page=true) #### Spring IOC源码分析 1、进入源码前准备TestBean和测试用例 此次源码分析主要以Bean初始化为主线 ``` public class ItBean { private TestBean testBean; public void setLagouBean(TestBean testBean) { this.testBean = testBean; } /** * 构造函数 */ public ItBean(){ System.out.println("ItBean 构造器..."); } } public class TestBean implements InitializingBean, ApplicationContextAware { private ItBean itBean; public void setItBean(ItBean itBean) { this.itBean = itBean; } /** * 构造函数 */ public TestBean(){ System.out.println("TestBean 构造器..."); } } ``` 2、ClasspathXmlApplicationContext 为例,进入源码流程 ``` /** * ApplicationContext是容器的高级接口,BeanFactory(顶级容器/根容器,规范了/定义了容器的基础行为) * Spring应用上下文,官方称之为 IoC容器(错误的认识:容器就是map而已;准确来说,map是ioc容器的一个成员,叫做单例池, singletonObjects,容器是一组组件和过程的集合,包括BeanFactory、单例池、BeanPostProcessor等以及之间的协作流程) * * Ioc容器创建管理Bean对象的,Spring Bean是有生命周期的 * 构造器执行、初始化方法执行、Bean后置处理器的before/after方法、:AbstractApplicationContext#refresh#finishBeanFactoryInitialization * Bean工厂后置处理器初始化、方法执行:AbstractApplicationContext#refresh#invokeBeanFactoryPostProcessors * Bean后置处理器初始化:AbstractApplicationContext#refresh#registerBeanPostProcessors */ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); TestBean testBean = applicationContext.getBean(TestBean.class); ``` 3、在TestBean 构造器方法处打断点,看在哪个方法对Bean进行了初始化 ![Bean初始化调用方法路径](https://images.gitee.com/uploads/images/2020/1123/160655_3ceee77e_797716.png "Bean初始化调用方法路径.png") 由上图可看出调用的方法路径 4、org.springframework.context.support.ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframework.context.ApplicationContext) ``` public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException { super(parent); setConfigLocations(configLocations); //是否刷新容器 if (refresh) { //初始化容器 refresh(); } } ``` 5、org.springframework.context.support.AbstractApplicationContext#refresh ```Java @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 第⼀步:刷新前的预处理 prepareRefresh(); // 第⼆步:获取BeanFactory;默认实现是DefaultListableBeanFactory,加载BeanDefinition 并注册到 BeanDefinitionRegistry ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 第三步:BeanFactory的预准备⼯作(BeanFactory进⾏⼀些设置,⽐如context的类加载器等) prepareBeanFactory(beanFactory); try { // 第四步:BeanFactory准备⼯作完成后进⾏的后置处理⼯作 postProcessBeanFactory(beanFactory); // 第五步:实例化并调⽤实现了BeanFactoryPostProcessor接⼝的Bean invokeBeanFactoryPostProcessors(beanFactory); // 第六步:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执⾏ registerBeanPostProcessors(beanFactory); // 第七步:初始化MessageSource组件(做国际化功能;消息绑定,消息解析); initMessageSource(); // 第⼋步:初始化事件派发器 initApplicationEventMulticaster(); // 第九步:⼦类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑 onRefresh(); // 第⼗步:注册应⽤的监听器。就是注册实现了ApplicationListener接⼝的监听器bean registerListeners(); // 第⼗⼀步:初始化所有的⾮懒加载的单例bean实例(未设置属性) //填充属性 //初始化⽅法调⽤(⽐如调⽤afterPropertiesSet⽅法、init-method⽅法) //调⽤BeanPostProcessor(后置处理器)对实例bean进⾏后置处 finishBeanFactoryInitialization(beanFactory); // 第⼗⼆步:完成context的刷新。主要是调⽤LifecycleProcessor的onRefresh()⽅法,并且发布事件(ContextRefreshedEvent) finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } } ``` 6、org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization **初始化Bean** ``` protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); // 实例化所有剩余(非惰性init)单例 beanFactory.preInstantiateSingletons(); } ``` 7、org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons **实例化所有剩余(非惰性init)单例** ``` @Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. List beanNames = new ArrayList<>(this.beanDefinitionNames); // 实例化所有剩余的(非延迟初始化)单例Bean,beanDefinitionNames在创建BeanFactory时就缓存了 for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //判断是否是非抽象类,是否是单例,是否是非懒加载 if (isFactoryBean(beanName)) { //判断是否是FactoryBean,是的话要加 & 前缀获取 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean factory = (FactoryBean) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction) ((SmartFactoryBean) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { //获取Bean getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } } ``` 8、org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String) 从容器中获取Bean 9、org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean getSingleton()方法从单例池获取Bean doGetBean()中先从单例池中获取,如果没有再创建,并放入单例池中,再获取 10、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[]) **创建Bean实例** 11、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean **创建Bean实例,填充Bean属性** ``` protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 实例化Bean BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); //创建Bean实例 } final Object bean = instanceWrapper.getWrappedInstance(); Class beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // 初始化Bean实例 Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); //填充Bean属性,循环依赖(三级缓存逻辑也就从此处开始) exposedObject = initializeBean(beanName, exposedObject, mbd); //初始化Bean } 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); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } ``` #### Spring循环依赖 1、发生在populateBean方法:填充属性,这一步主要是对bean的依赖属性进行注入(@Autowired), 此时会出现A依赖于B,B又依赖于A这种情况; 2、三级缓存: - singletonObjects:用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用 - earlySingletonObjects:提前曝光的单例对象的cache,存放原始的 bean 对象(尚未填充属性),用于解决循环依赖 - singletonFactories:单例对象工厂的cache,存放 bean 工厂对象,用于解决循环依赖 3、getSingleton方法: - 先从一级缓存singletonObjects中去获取。(如果获取到就直接return) - 如果获取不到或者对象正在创建中(isSingletonCurrentlyInCreation()),那就再从二级缓存earlySingletonObjects中获取。(如果获取到就直接return) - 如果还是获取不到,且允许singletonFactories(allowEarlyReference=true)通过getObject()获取。就从三级缓存singletonFactory.getObject()获取。(如果获取到了就从singletonFactories中移除,并且放进earlySingletonObjects, 其实也就是从三级缓存移动到了二级缓存)

循环依赖方法执行
#### Spring Aop源码分析 1、编写配置类SpringConfig、AopTestBean和AopTestAspect ``` /** * @Description: 配置类 * @Author: Created by OrangeZh * @Date: Created in 2020/11/25 15:00 */ @Configuration @ComponentScan("com.ozdemo") @EnableAspectJAutoProxy //开启spring对注解AOP的⽀持 public class SpringConfig { } /** * @Description: Aop测试对象 * @Author: Created by OrangeZh * @Date: Created in 2020/11/25 14:38 */ @Component public class AopTestBean { public void test(){ System.out.println("AopTestBean.test方法执行了"); } } /** * @Description: 切面类 * @Author: Created by OrangeZh * @Date: Created in 2020/11/25 14:40 */ @Component @Aspect public class AopTestAspect { @Pointcut("execution(* com.ozdemo.test.AopTestBean.*(..))") public void pointcut(){ } @Before("pointcut()") public void before() { System.out.println("before method ......"); } @After("pointcut()") public void after() { System.out.println("after method ......"); } } ``` 2、编写测试用例进入源码 ``` @Test public void testAOP() { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class); AopTestBean aopTestBean = applicationContext.getBean(AopTestBean.class); aopTestBean.test(); } ``` ![Aop动态代理Bean](https://images.gitee.com/uploads/images/2020/1125/160436_2b8bdeab_797716.png "Aop动态代理Bean.png") 由上图我们可以看出getBean 之前,AopTestBean 对象已经产⽣(即在第⼀⾏初始化代码中完成),⽽且该对象是⼀个代理对象(Cglib代理对象),我们断定,容器初始化过程中⽬标Ban已经完成了代理,返回了代理对象。 3、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition) **初始化Bean** 这一步的源码就接着IOC的11步继续了 ``` /** * * 初始化Bean * 包括Bean后置处理器初始化 * Bean的⼀些初始化方法的执行init-method * AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization * Bean的实现的声明周期相关接口的属性注入 */ protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // 执⾏所有的AwareMethods invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 执⾏所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前的处理器方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 这⾥就开始执行afterPropertiesSet(实现了InitializingBean接口)方法和initMethod 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()) { // 整个Bean初始化完成,执⾏后置处理器⽅法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } ``` 4、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization 遍历执行后置处理器 5、org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization 创建代理对象的后置处理器 ``` @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { // 检查下该类是否已经暴露过了(可能已经创建了,⽐如A依赖B时,创建A时候,就会先去创建B,当真正需要创建B时,就没必要再代理⼀次已经代理过的对象),避免重复创建 Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } ``` 6、org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary ``` protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } //得到所有候选Advisor,对Advisors和bean的⽅法双层遍历匹配,最终得到⼀个List,即specificInterceptors 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; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } ``` 7、org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy **为指定 bean 创建代理对象** ``` protected Object createProxy(Class beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } //创建代理工厂 ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); //根据⼀些情况判断是否要设置proxyTargetClass=true if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } // 把指定和通⽤拦截对象合并, 并都适配成Advisor Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } //创建代理对象 return proxyFactory.getProxy(getProxyClassLoader()); } ``` 8、org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader) ``` public Object getProxy(@Nullable ClassLoader classLoader) { //创建aop代理对象 提供了两种:jdk proxy, cglib return createAopProxy().getProxy(classLoader); } ``` org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy 创建代理对象,jdk proxy, cglib org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy ``` /** * 这里决定创建代理对象是用JDK Proxy,还是⽤ Cglib 了,最简单的从使用方面使⽤来说:设置proxyTargetClass=true强制使⽤Cglib 代理,什么参数都不设并且对象类实现了接口则默认用JDK 代 理,如果没有实现接⼝则也必须⽤Cglib * @param config the AOP configuration in the form of an * AdvisedSupport object * @return * @throws AopConfigException */ @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); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } } ``` 9、org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader) 创建CglibAopProxy,⽣成代理类,并且创建⼀个代理类的实例