Spring核心思想(一)

注意: IOC和AOP不是spring框架提出来的,在spring框架之前就已经有了,只不过更偏向于理论化,spring在技术层面上把这两个思想做了非常好的实现(Java)


1.什么是IOC?
   IoC Inversion of Control (控制反转/反转控制) 注意他是一个思想,不是一个技术实现
   描述的事情:Java开发领域对象的创建、管理问题
   传统的开发方式:比如类A依赖于类B,往往会在类A中new一个类B的对象
   IOC思想下的开发方式:我们不用自己去new对象了,而是由Ioc容器(Spring框架)去帮助我们实例化对象并且管理它,我们需要使用到哪个对象,就去问IoC容器要即可,这样看起来我们丧失了一个权力(创建、管理对象的权力),但是得到了一个福利,那就是不用考虑对象的创建、管理等一系列事情

   为什么叫做控制反转?
      控制: 指的是对象的创建(实例化、管理)的权力
      反转: 控制权交给了外部环境了(Spring框架,Ioc容器)

下面插入一张图来表示这种思想
Spring核心思想(一)_第1张图片

Ioc解决了什么问题

      Ioc解决了对象之间的耦合问题
Spring核心思想(一)_第2张图片

Ioc和DI的区别?

DI: 依赖注入
IOC和DI描述的是同一件事情,只不过角度不一样罢了
Spring核心思想(一)_第3张图片

下面以一个转账案例来说明:

Spring核心思想(一)_第4张图片

2.Ioc实现:

Spring核心思想(一)_第5张图片

==2.==什么是AOP

AOP:Aspect oriented Programming面向切面编程/面向方面编程

Aop是oop的延续,从OOP说起

OOP三大特征:封装、继承和多态

oop是一种垂直继承体系

Spring核心思想(一)_第6张图片
oop编程思想可以解决大多数代码重复问题,但是有一些情况是处理不了的,比如下面的在顶级父类Animal中的多个方法中相同位置出现了重复代码,OOP就解决不了
Spring核心思想(一)_第7张图片

横切逻辑代码:假设我们在所有的方法执行前都要打印相同的一段话,那就意味着我们需要在每个方法最顶层添加上sout("打印一段话")

Spring核心思想(一)_第8张图片

横切逻辑代码存在什么问题:

  • 横切代码重复问题
  • 横切逻辑代码和业务代码混杂在一起,代码臃肿,维护不方便

AOP出场,AOP独辟蹊径提出横向抽取机制,将横向逻辑代码和业务代码分开

Spring核心思想(一)_第9张图片

代码拆分容易,那摩如何在不改变原有业务逻辑的情况下,悄无声息的把横切逻辑代码应用到原有的业务逻辑中,达到和原来一样的效果,这个是比较难的

AOP在解决什么问题?

在不改变原有业务逻辑情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复

为什么叫做面向切面编程

: 指的是横切逻辑,原有业务逻辑代码我们不能动,只能操作横切逻辑代码,所以面向横切逻辑
:横切逻辑代码往往要影响很多个方法,每一个方法都如同一个点,多个点构成一个面,有一个面的概念在里面

AOP的底层实现原理就是基于动态代理的,下面来通过代码来实现动态代理:再次之前先要知道啥是静态代理,请看静态代理模式

1.抽象出一个公共的接口,表示实例对象和代理对象都要做的事情

/**
 * 接口,租房
 * jdk动态代理,
 * cglib代理(需要开发者导入jar包)
 */
public interface IRentingHouse {
    void rentHouse();
}

2.委托对象,也就是实例对象想要做的事

/**
 * 委托方(委托对象)
 */
public class RentingHouseImpl implements IRentingHouse {

    @Override
    public void rentHouse() {
        System.out.println("我要租用一室一厅的房子");
    }
}

3.代理对象,也就是代理真实对象去干真实对象想做的事情

package aop.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JdkProxy {

    public static void main(String[] args) {

           // 委托方,委托对象
        IRentingHouse rentingHouse = new RentingHouseImpl();

           // 获取代理对象
        IRentingHouse proxy =(IRentingHouse) Proxy.newProxyInstance(rentingHouse.getClass().getClassLoader(), rentingHouse.getClass().getInterfaces(),
                new InvocationHandler() {

                    /**
                     *
                     * @param proxy  代理对象
                     * @param method 实例对象要调用的方法
                     * @param args 实例对象要调用方法需要传递的参数
                     * @return  
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object result = null;

                        // 写增强逻辑
                        System.out.println("中介 (代理) 收取服务费3000元");
                            // 调用原有业务逻辑
                        result = method.invoke(rentingHouse, args);
                        System.out.println("客户信息卖了3毛钱");
                        return result;
                    }
                });

                proxy.rentHouse();

    }
}

4.启动main方法测试即可

5.优化,将该代理对象的生成封装成工厂方法

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 代理对象工厂:生成代理对象的
 */
public class ProxyFactory {

    private ProxyFactory(){

    }

    private static ProxyFactory proxyFactory = new ProxyFactory();

    public static ProxyFactory getInstance(){
        return proxyFactory;
    }

    /**
     * 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;

                        // 写增强逻辑
                        System.out.println("中介 (代理) 收取服务费3000元");
                        // 调用原有业务逻辑
                        result = method.invoke(obj, args);
                        System.out.println("客户信息卖了3毛钱");
                        return result;
                    }
                });
    }
}

6.启动测试

public class JdkProxyTest {
    public static void main(String[] args) {
        IRentingHouse rentingHouse = new RentingHouseImpl();  // 委托对象--委托方

        // 从代理对象工厂获取代理对象
        IRentingHouse jdkProxy =(IRentingHouse) ProxyFactory.getInstance().getJDKProxy(rentingHouse);
        jdkProxy.rentHouse();
    }
}

基于cglib实现的动态代理

  1. 导入依赖的jar包
<dependency>
     <groupId>cglib</groupId>
     <artifactId>cglib</artifactId>
     <version>2.1.2</version>
 <dependency>    

2.代码实现
Spring核心思想(一)_第10张图片

你可能感兴趣的:(spring,spring)