【Spring系列】Spring两大核心思想-Bean和面向切面编程AOP是什么

举报
gentle_zhou 发表于 2022/03/29 15:11:12 2022/03/29
【摘要】 Spring有很多概念,但其中最核心的两个概念就是Bean 和 AOP面向切面编程(Aspect Oriented Programming)。

Spring有很多概念,但其中最核心的两个概念就是Bean 和 AOP面向切面编程(Aspect Oriented Programming)。

众所周知,Java是面向对象的编程语言,object对象就是其最基础最核心的概念,一切皆可以是对象;Spring作为一个开源的Java 开发应用框架,其最基础的概念就是Bean了,项目里所有的类都可以认为是一个Bean;理解Bean 至关重要,而在理解过程中,又会延伸出控制反转和依赖注入这两个概念。至于AOP,面向切面编程和OOP面向对象编程一样,是一种编程范式,不同的是Spring中的AOP 是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。


【Bean】

先来看看官方文档[1]对于Bean的定义:

“In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.”

翻译过来就是说,“在Spring中,beans是那些组成应用主干并且由Spring IoC容器管理的若干对象。一个bean就是由Spring IoC容器实例,组装和管理的对象。或则简单来说,一个bean就是程序中一个或多个对象。Beans 和它们的依赖,由容器用到的配置元数据所体现出来”。Bean的规范:所有属性为private,提供默认构造方法,提供getter和setter,实现serializable接口。

上面定义中提到的IoC容器是什么呢?

那么就需要先知道什么是IoC,Inversion of Control,控制反转。它也被称为Dependency Injection,依赖注入。还是先上官方文档的理解:在控制反转过程中,对象只能通过构造函数参数,工厂方法的参数,对象实例被实例化后或从工厂方法返回后可以设置在它上面的属性 来定义对象的依赖关系。容器然后再在创建bean的时候把这些依赖注入其中。从根本上来讲,这个过程与bean本身通过使用直接构造类或类似Service Locator模式的机制来控制bean自己的依赖的实例或者位置的过程相反,因此被称为控制反转。

换句话来说,控制反转是一个对象定义其依赖关系的过程,它通过依赖注入的方式实现了对象之间的松耦合关系。而IoC容器相当于一个辅助程序,在程序运行时,控制着对象的实例化,依赖的实例化 以及 依赖的注入,动态绑定对象和依赖的使用关系。

上面提到的依赖关系指的是可被利用的一种对象,依赖注入则是指将这些可被利用的对象传递给需要使用的从属对象;我们可以这么理解,依赖关系是一种服务,从属对象是客户,我们需要将服务传递给客户,而不是让客户来建立或寻找服务。

因此,在Spring中,我们不需要自己new去实例化对象,Spring会控制new的过程。Sping启动的时候会把所需要的类实例化成对象,如果需要依赖,则先实例化依赖,然后实例化当前类。因为依赖必须通过构建函数传入,所以实例化的时候,当前类就会接收并保存所有依赖的对象。

代码层面的例子来说,假设我们有一个Animal类:

public class Animal {
    private String type;     // 品种
    private int size;        // 大小

    public Animal(String type, int size) {
        this.type = type;
        this.size = size;
    }
}

而我们有另一个类Dog类依赖Animal类,符合IoC的做法:

public class Dog{
    private Animal animal;

    public Dog(Animal animal) {
        this.animal = animal;
    }
}


而不符合IoC的做法则是直接用new实例化,或者通过非构造函数传入依赖:

// 直接在Dog里实例化Animal类
public class Dog {
    private Animal animal = new Animal("Dog", 2);
}

// 通过 非构造函数 传入依赖
public class Dog {
    private Animal animal;
    
    public void init(Animal animal) {
        this.animal = animal;
}

【AOP面向切面编程】

AOP面向切面编程,可以利用其对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低;是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。动态代理其实就是在运行时动态的生成目标对象的代理对象在代理对象中对目标对象的方法进行增强 [2]。

切面Asepect,简单来说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度。AOP则利用一种称为“横切”的技术,破解开封装的对象内部,并将哪些影响多个类的公共行为封装到一个可重用模块-“Aspect”[3]。

AOP的优势:对原有代码毫无入侵性,把和主业务无关的事情,放到代码外面去做,有利于未来的可操作性和可维护性。


【引用的材料链接】

1. https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/beans.html

2. https://www.awaimai.com/2597.html

3. https://blog.csdn.net/u010688011/article/details/79431778?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。