Source source = (Source) context.getBean("source");

    System.out.println(source.getFruit());

    System.out.println(source.getSugar());

    System.out.println(source.getSize());

}

}


1.  运行测试代码,可以正常拿到 xml 配置的 bean

![](https://s2.51cto.com/images/20210913/1631472034684199.jpg)

*   **总结:**

*   **传统的方式:**  

    通过new 关键字主动创建一个对象

*   **IOC方式:**  

    对象的生命周期由Spring来管理,直接从Spring那里去获取一个对象。 IOC是反转控制 (Inversion Of Control)的缩写,就像控制权从本来在自己手里,交给了Spring。  

    ![获取对象方式的转变](https://s2.51cto.com/images/20210913/1631472034950522.jpg)

> 参考地址:[这里](

)

DI:Dependency Injection(依赖注入)

*   指 Spring 创建对象的过程中,**将对象依赖属性(简单值,集合,对象)通过配置设值给该对象**

继续上面的例子

1.  在 Packge【pojo】下新建一个【JuiceMaker】类:

package pojo;

public class JuiceMaker {

// 唯一关联了一个 Source 对象

private Source source = null;

/* setter and getter */

public String makeJuice(){

    String juice = "xxx用户点了一杯" + source.getFruit() + source.getSugar() + source.getSize();

    return juice;

}

}


1.  在 xml 文件中配置 JuiceMaker 对象:

*   **注意:**这里要使用 ref 来**注入**另一个对象

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean name="source" class="pojo.Source">

    <property name="fruit" value="橙子"/>

    <property name="sugar" value="多糖"/>

    <property name="size" value="超大杯"/>

</bean>

<bean name="juickMaker" class="pojo.JuiceMaker">

    <property name="source" ref="source" />

</bean>

</beans>


1.  在 【TestSpring】 中添加如下代码:

package test;

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import pojo.JuiceMaker;

import pojo.Source;

public class TestSpring {

@Test

public void test(){

    ApplicationContext context = new ClassPathXmlApplicationContext(

            new String[]{"applicationContext.xml"}

    );

    Source source = (Source) context.getBean("source");

    System.out.println(source.getFruit());

    System.out.println(source.getSugar());

    System.out.println(source.getSize());

    JuiceMaker juiceMaker = (JuiceMaker) context.getBean("juickMaker");

    System.out.println(juiceMaker.makeJuice());

}

}


1.  运行测试代码:

![](https://s2.51cto.com/images/20210913/1631472034936001.jpg)

**总结:**IoC 和 DI 其实是同一个概念的不同角度描述,DI 相对 IoC 而言,**明确描述了“被注入对象依赖 IoC 容器配置依赖对象”**

IoC 如何实现的

最后我们简单说说IoC是如何实现的。想象一下如果我们自己来实现这个依赖注入的功能,我们怎么来做? 无外乎:

1.  读取标注或者配置文件,看看JuiceMaker依赖的是哪个Source,拿到类名

2.  使用反射的API,基于类名实例化对应的对象实例

3.  将对象实例,通过构造函数或者 setter,传递给 JuiceMaker

我们发现其实自己来实现也不是很难,Spring实际也就是这么做的。这么看的话其实IoC就是一个工厂模式的升级版!当然要做一个成熟的IoC框架,还是非常多细致的工作要做,Spring不仅提供了一个已经成为业界标准的Java IoC框架,还提供了更多强大的功能,所以大家就别去造轮子啦!希望了解IoC更多实现细节不妨通过学习Spring的源码来加深理解!

> 引用地址:[这里](

)

* * *

Spring AOP 简介

-------------

如果说 IoC 是 Spring 的核心,那么面向切面编程就是 Spring 最为重要的功能之一了,在数据库事务中切面编程被广泛使用。

AOP 即 Aspect Oriented Program 面向切面编程

首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能。

*   **所谓的核心业务**,比如登陆,增加数据,删除数据都叫核心业务

*   **所谓的周边功能**,比如性能统计,日志,事务管理等等

周边功能在 Spring 的面向切面编程AOP思想里,即被定义为切面

在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发,然后把切面功能和核心业务功能 "编织" 在一起,这就叫AOP

AOP 的目的

AOP能够将那些与业务无关,**却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来**,便于**减少系统的重复代码**,**降低模块间的耦合度**,并**有利于未来的可拓展性和可维护性**。

AOP 当中的概念:

*   切入点(Pointcut)  

    在哪些类,哪些方法上切入(**where**)

*   通知(Advice)  

    在方法执行的什么实际(**when:**方法前/方法后/方法前后)做什么(**what:**增强的功能)

*   切面(Aspect)  

    切面 = 切入点 + 通知,通俗点就是:**在什么时机,什么地方,做什么增强!**

*   织入(Weaving)  

    把切面加入到对象,并创建出代理对象的过程。(由 Spring 来完成)

AOP 编程

1.  在 Packge【service】下创建 【ProductService】类:

package service;

public class ProductService {

public void doSomeService(){

    System.out.println("doSomeService");

}

}


1.  在 xml 文件中装配该 bean:

<bean name="productService" class="service.ProductService" />


1.  在【TestSpring】中编写测试代码,运行:

![](https://s2.51cto.com/images/20210913/1631472034558903.jpg)

1.  在 Packge【aspect】下准备日志切面 【LoggerAspect】类:

package aspect;

import org.aspectj.lang.ProceedingJoinPoint;

public class LoggerAspect {

public Object log(ProceedingJoinPoint joinPoint) throws Throwable {

    System.out.println("start log:" + joinPoint.getSignature().getName());

    Object object = joinPoint.proceed();

    System.out.println("end log:" + joinPoint.getSignature().getName());

    return object;

}

}



# 写在最后

学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!

最后再分享的一些BATJ等大厂20、21年的面试题,把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](https://ali1024.coding.net/public/P7/Java/git)**

![蚂蚁金服三面直击面试官的Redis三连,Redis面试复习大纲在手,不慌](https://s2.51cto.com/images/20210913/1631472034322383.jpg)

Mybatis面试专题

![蚂蚁金服三面直击面试官的Redis三连,Redis面试复习大纲在手,不慌](https://s2.51cto.com/images/20210913/1631472035178507.jpg)

MySQL面试专题

![蚂蚁金服三面直击面试官的Redis三连,Redis面试复习大纲在手,不慌](https://s2.51cto.com/images/20210913/1631472035443114.jpg)

并发编程面试专题