代理模式 最典型的应用莫过于Spring了 Spring 的核心是 IOC容器和AOP切面
IOC:
当某个 Java 实例需要另一个 Java 实例时,传统的方法是由调用者创建被调用者的实例(例如,使用 new 关键字获得被调用者实例),而使用 Spring框架后,被调用者的实例不再由调用者创建,而是由 Spring 容器创建,这就是控制反转( Inversion of Control ), 我觉得有必要先了解软件设计的一个重要思想:依赖倒置原则(Dependency Inversion Principle )。把原本的高层建筑依赖底层建筑“倒置”过来,变成底层建筑依赖高层建筑。高层建筑决定需要什么,底层去实现这样的需求,但是高层并不用管底层是怎么实现的。这样就不会出现前面的“牵一发动全身”的情况。控制反转(Inversion of Control) 就是依赖倒置原则的一种代码设计的思路。具体采用的方法就是所谓的依赖注入(Dependency Injection),Spring 容器在创建被调用者的实例时,会自动将调用者需要的对象实例注入给调用者,这样,调用者通过 Spring 容器获得被调用者实例,这称为依赖注入。
具体关系梳理如图:
而IoC Container在进行这个工作的时候,它先从最上层开始往下找依赖关系,到达最底层之后再往上一步一步new(有点像深度优先遍历):
这里IoC Container可以直接隐藏具体的创建实例的细节,在我们来看它就像一个工厂:
我们就像是工厂的客户。我们只需要向工厂请求一个Car实例,然后它就给我们按照Config创建了一个Car实例。我们完全不用管这个Car实例是怎么一步一步被创建出来。
其次Spring里面有很多@注解 如何自定义自己的@注解?
https://www.cnblogs.com/wenq001/p/9144278.html
说明1:@Target、@Retention、@Inherited、@Documented为元注解(meta-annotation),它们是负责注解其他注解的。
1:Target注解 :指明注解支持的使用范围,取值可以参考ElementType :
- ElementType.TYPE //类、接口、枚举
- ElementType.FIELD //属性
- ElementType.METHOD //方法
- ElementType.PARAMETER //参数
- ElementType.CONSTRUCTOR //构造器
- ElementType.LOCAL_VARIABLE //局部变量
- ElementType.ANNOTATION_TYPE //注解
- ElementType.PACKAGE //包
2:Retention注解 :指明注解保留的时间长短,取值参考枚举RetentionPolicy :
- SOURCE //源文件中保留
- CLASS //class编译时保留
- RUNTIME //运行时保留
3:Inherited 注解:指明该注解类型被自动继承。如果一个annotation注解被@Inherited修饰,那么该注解作用于的类的子类也会使用该annotation注解。
4:Document 注解:指明拥有这个注解的元素可以被javadoc此类的工具文档话。
说明2:在自定义注解中定义的属性有 default ,使用该注解的时候可以不填写该属性,否则该属性为必填,不填会提示错误。
上面自定义注解就定义好了,接下来就可以在Target指定的范围内使用该注解了,比如上面定义的注解是使用在 METHOD 上的,可以这样使用。
要想注解生效就必须用到AOP去做动态代理了。
Spring的最底层是一个核心的Serverlet。 DispatcherServlet 实现Servelet方法。
https://www.bilibili.com/video/BV17J411h7QZ?t=1992
AOP的本质是动态代理
在原理对象的基础上生成一个动态代理的对象,动态代理对象那个包含了原来对象的功能参数,然后逻辑功能的增强,比如事务,日志,以后spring不直接调用原来的对象,而是去调用他的一个代理对象,遵循了开放封闭的原则(对修改封闭,对功能添加开放,有点Python语法糖的味道。