我的控制反转,依赖注入和面向切面编程的理解

感谢http://blog.xiaohansong.com/2015/10/21/IoC-and-DI/ 的供图


1.什么是控制? 如下图所示,我们看到了 软件系统中 对象的 高耦合现象。全体齿轮的转动由一个对象来控制,如类B。



2.什么是 控制反转? 是用来对对象进行解耦借助第三方实现具有依赖关系的的对象之间的解耦。这个第三方就是 ioc 容器。引入了 ioc 容器后,对象 A、B、C、D 之间没有了依赖关系全体齿轮转动的控制权交给 容器。这时候齿轮转动控制权不属于任何对象,而属于ioc 容器,所以控制权反转了,从 某个对象 转到了 ioc 容器。


3. 什么是依赖注入?
3.1 什么是依赖?依赖就是指一种关系,如果 在类A中 创建了 类B的实例,我们说 类A 依赖 类B。
3.2 看个荔枝:
public class class A{
B b;
public A(){
b = new B();
}
void func(){
b.func();
}
}
出现的问题(problems):
  • 问题1:如果现在要改变 类 B 生成方式,如需要用new B(String name)初始化 B,需要修改 类A中的源代码;
  • 问题2:如果想测试不同 B 对象对 A 的影响很困难,因为 B 的初始化被写死在了 A 的构造函数中
  • 问题3:如果要对类B的实例进行调试时,就必须在类A中对类B的实例进行测试,增加了测试难度和复杂度;因为当出现问题时,不知道 是 类A的问题 还是 类B的问题;
解决方法:
public class class A{
B b;
public A(B b){
this.b = b;
}
void func(){
b.func();
}
}
3.3)依赖注入定义: 将B对象实例 作为类A的构造器参数进行传入,在调用类A 构造器之前,类B实例已经被初始化好了。像这种非自己主动初始化依赖,而通过外部传入依赖对象的方式,我们就称为依赖注入

4.依赖反转
4.1 根据依赖注入的定义: 被依赖者对象并不是依赖者自己主动初始化,而是通过外部传入被依赖者的方式,那么被依赖者对象类型 可以是 其 本身,也可以使其实现类或继承子类;
4.2 所以,经过分析,被依赖者的对象类型 并不是 依赖者自身可以决定的,(当然传统的程序设计方式是依赖者 决定的),而是由外部创建者决定的,所以 被依赖者类型的决定权反转了。对于spirng来说 ,就是由 spring容器决定的;

4.3 依赖反转定义:被依赖者的 对象类型 并不是由依赖者自身可以决定的,而是由 外部创建者决定的,外部传入什么类型的对象 就是 什么类型的对象 , 依赖者对其一无所知;

=======================================================================================
【AOP
转自:http://docs.jboss.org/aop/1.0/aspect-framework/userguide/en/html/what.html
【1】What is it? 面向切面编程是什么?
1)切面定义:一个切面是通常指散布在方法,类,对象层次结构或甚至整个对象模型中的共同特征。 它是看起来和气味的行为差不多,它应该有结构,但你不能用代码在传统的面向对象技术中表示这种结构。
2)切面荔枝:例如,度量(时间,用于度量运行某个代码片需要花费多长时间)是一个常见切面。 要从应用程序生成有用的日志,您必须(通常自由地)在代码中散布信息性消息。 然而,度量是你的类或对象模型真正不应该关注的东西。 毕竟,度量与您的实际应用无关:它不代表客户或帐户,并且不实现业务规则。 它只是正交。
3)横切关注点定义:在AOP中,像度量这样的特征称为横切关注点,因为它是一种“截断”对象模型中多个点但仍然截然不同的行为。作为一种开发方法,AOP建议您抽象和封装横切关注点。
4)横切关注点荔枝:例如,假设您想要向应用程序添加代码以测量调用特定方法所需的时间。 在纯Java中,代码看起来像下面这样。
public class BankAccountDAO {public void withdraw(double amount)  {long startTime = System.currentTimeMillis();try {// Actual method body...}finally {long endTime = System.currentTimeMillis() - startTime;System.out.println("withdraw took: " + endTime);}}
}
代码分析)虽然这段代码工作,这个方法有一些问题:
  • 打开和关闭指标是非常困难的,因为您必须手动将try> / finally块中的代码添加到要基准的每个方法或构造函数。
  • 分析代码真的不属于你的应用程序代码。 它使你的代码膨胀和更难读,因为你必须在一个try / finally块中包含时间。
  • 如果要扩展此功能以包括方法或失败计数,或者甚至将这些统计信息注册到更复杂的报告机制,则必须再次修改许多不同的文件。
这种度量方法很难维护,扩展和扩展,因为它分散在整个代码库中。 这只是一个很小的例子! 在许多情况下,OOP可能不总是向类添加指标的最佳方法。
面向方面的编程提供了一种封装这种类型的行为功能的方法。 它允许您添加行为,如度量“围绕”您的代码。 例如,AOP为您提供了程序控制,以指定您希望在执行代码的实际主体之前调用BankAccountDAO来执行度量方面。

【2】在JBoss 切面编程中创建切面
1)简而言之,所有AOP框架定义了两个东西:一种实现横切关注点的方法,以及一个编程语言或一组标签 -以指定如何应用这些代码片段。(一种是 定义横切关注点的方法,二是指定该横切关注点在何处使用)
2)让我们来看看JBoss AOP,它的横切关注点,以及如何在JBoss中实现一个度量方面。
在JBoss AOP中创建度量方面的第一步是将度量特性封装在自己的Java类中。 清单二将清单One的BankAccountDAO.withdraw()方法中的try / finally块提取为Metrics,这是一个JBoss AOP拦截器类的实现。
清单二:在JBoss AOP拦截器中实现度量
public class Metrics implements org.jboss.aop.Interceptor
03.   public Object invoke(Invocation invocation) throws Throwable {
05.     long startTime = System.currentTimeMillis();
06.     try {
08.       return invocation.invokeNext();
09.     }
10.     finally {
12.       long endTime = System.currentTimeMillis() - startTime;
13.       java.lang.reflect.Method m = ((MethodInvocation)invocation).method;
14.       System.out.println("method " + m.toString() + " time: " + endTime + "ms");
15.     }
16.   }
17. }
对以上代码的分析:
  • 在JBoss AOP下,Metrics类包装withdraw():当调用代码调用withdraw()时,AOP框架将方法调用分解为其部分,并将这些部分封装到一个调用对象中。 然后框架调用位于调用代码和实际方法体之间的任何方面。
  • 当AOP框架解析方法调用时,它在第3行调用Metric的invoke方法。第8行包装并委托给实际的方法,并使用一个封闭的try / finally块来执行定时。 第13行从调用对象获取有关方法调用的上下文信息,而第14行显示方法名称和计算的度量。
  • 将度量代码放在其自己的对象中允许我们以后轻松扩展和捕获额外的测量。现在,度量被封装到一个方面,让我们看看如何应用它。
【3】JBoss AOP中切面的应用
要应用一个方面,您定义何时执行方面代码。 这些执行点被称为切入点。 类似于切入点是一个正则表达式。 正则表达式匹配字符串时,切入点表达式匹配应用程序中的事件/点。 例如,有效的切入点定义将是“对于JDBC方法executeQuery()的所有调用,调用验证SQL语法的方面”。

我的总结(AOP)
1)切面的抽象型定义:切面是散布在 方法,类,对象层次结构或 整个对象模型中的共同特征;(是一组特征)
2)切面荔枝:如 我们要对某方法的执行时间进行统计,代码如下:
public class BankAccountDAO {public void withdraw(double amount)  {long startTime = System.currentTimeMillis();try {// Actual method body...}finally {long endTime = System.currentTimeMillis() - startTime;System.out.println("withdraw took: " + endTime);}}
}
其中 有关于统计时间的都是特征,它们的共性都是因为要统计时间而 添加到 方法中的代码块;那所以这些代码块就组成了 切面;
3)以上代码块出现了问题
问题1)代码重用率低:必须手动将该 切面代码添加到 要统计方法执行时间的方法中;
问题2)代码膨胀和可读性低:计时代码真的不用你去关心,这些切面代码只会让你的代码更加 膨胀和难读,因为你必须在一个try / finally块中包含时间, 但这个时间与我们 方法的执行没有任何关系;
问题3)不利于代码扩展(代码耦合性高):如果要扩展此功能以包括方法或失败计数,或者甚至将这些统计信息注册到更复杂的报告机制,则必须再次修改许多不同的文件;
最后的最后:这种时间度量方法很难维护,扩展和扩展,因为它分散在整个代码库中;
4)aop 是干什么的?
4.1)intro:面向切面编程提供了一种封装切面行为的方法。AOP提供了程序控制,以指定您希望在执行代码的实际主体之前调用 时间统计方法 来执行执行时间度量。
4.2)所有AOP框架定义了两个东西:一种实现横切关注点的方法,以及一个编程语言或一组标签 -以指定如何应用这些代码片段。(一种是 定义横切关注点的方法,二是指定该横切关注点在何时何处使用)

5)如何定义aop中横切关注点的方法 和 指定该横切关注点的应用地点
5.1)定义横切关注点:将切面代码度量特性封装在自己的Java类中
public class Metrics implements org.jboss.aop.Interceptorpublic Object invoke(Invocation invocation) throws Throwable {long startTime = System.currentTimeMillis();try {return invocation.invokeNext(); // 调用真正的实体方法}finally {long endTime = System.currentTimeMillis() - startTime;java.lang.reflect.Method m = ((MethodInvocation)invocation).method;System.out.println("method " + m.toString() + " time: " + endTime + "ms");}}}
5.2)横切关注点在何时何地使用?
要应用一个切面,您定义何时执行切面代码。 这些执行点被称为切入点。切入点类似于是一个正则表达式。 正则表达式匹配字符串时,切入点表达式匹配应用程序中的事件/点。
看个 切入点的定义: @Before("execution(** concert.Performance.perform(..))")


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330928.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Spring Boot中使用切面统一处理自定义的异常

最近我们将项目的一个单独模块提取了一个微服务,这个微服务主要负责其他系统的接入。目的是发布主项目的时候不会影响到其他系统接入。在提取出的微服务中,需要定义一个正常返回的报文和异常返回的报文。正常返回报文就是正常业务返回的数据报文&#xf…

Java 8的新特性—终极版

转载自 Java 8的新特性—终极版 1. 简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本。这个版本包含语言、编译器、库、工具和JVM等方面的十多个新特性。在本文中我们将学习这些新特性,并用实际的例子说明在…

ReviewForJob——java虚拟机的垃圾回收策略(个人总结)

理解jvm的垃圾回收策略,需要解决以下3个问题问题1:哪些内存需要回收?问题2:什么时候进行回收?问题3:怎样来回收?【解决问题1】哪些内存需要回收?jvm的内存区域有5大块:1&…

使用静态代理模式实现公用的报表导出功能

先聊一下什么是代理模式? 代理模式 给某个对象提供一个代理对象,并由代理独享控制对原对象的引用。什么意思呢?代理模式就有点像我们生活中常见的中介。 举个例子,我想买辆二手车,第一种方式是自己去找车源&#xff…

java前台线程(普通线程) 和 后台线程

【1】普通线程: 就是指 用户 创建的一般线程,具有个体性,不具有提供公共服务的性质,因此, 通常需要我们在 线程的 循环语句中 手动编写 循环结束语句,也即 线程运行终止的条件语句; 【2】后台线…

mysql中使用CASE WHEN

简单的使用CASE WHEN CASE SCORE WHEN A THEN 优 ELSE 不及格 END CASE SCORE WHEN B THEN 良 ELSE 不及格 END CASE SCORE WHEN C THEN 中 ELSE 不及格 END上面的sql等同于 CASE SCORE WHEN A THEN 优 WHEN B THEN 良 WHEN C THEN 中 ELSE 不及格 ENDTHEN后面的值与ELSE后面…

Java生成随机数的几种高级用法

转载自 进阶 | Java生成随机数的几种高级用法!言归正传,众所周知,随机数是任何一种编程语言最基本的特征之一。而生成随机数的基本方式也是相同的:产生一个0到1之间的随机数。看似简单,但有时我们也会忽略了一些有趣的…

Java 可重入锁内存可见性分析

转载自 深度好文 | Java 可重入锁内存可见性分析一个习以为常的细节之前在做 ReentrantLock 相关的试验,试验本身很简单,和本文相关的简化版如下:(提示:以下代码均可左右滑动) private static ReentrantLoc…

java正则表达式 ^expr 和 [^expr] 和 ^[^expr]的比较

public class Main {private static String[] array {"Jav", "Java", "Hello"}; public static void main(String[] args) {String[] regexs {"^Java", // 以 Java开头的字符串"[^Java]",// 除了 J a v a 之外 的任何字符…

优秀 Java 程序员写代码的风格

转载自 涨姿势 | 优秀 Java 程序员写代码的风格今天突发奇想,对编码习惯和 编程风格 很感兴趣,于是乎,找了一下关于编程风格(Java篇)的资料,希望对爱好编码或者开始学习编码的同学有帮助!来自《…

2017尼毕鲁笔试算法题

【1】题目: 给定一个无序数组,找到最长的单调自增子序列(不一定连续,但是顺序不能乱)的长度; 【2】看个荔枝:给定数组 [10, 9, 2, 5, 3, 7, 101, 18] 输出结果为 [2, 3, 7, 101]。。算法时间…

2018年不能错过的 14 个 Java 库

转载自 2018年不能错过的 14 个 Java 库下面是整理给你的 2018 年不应该错过的 14 个 Java 库包清单,多多少少大家应该都接触过一些,如果还没听过那就OUT了。GuiceGuice是一个Java 6以上支持依赖注入框架。由谷歌提供。OkHttpHTTP是现代网络的通讯方式。…

Spring MVC Boot Cloud 技术教程汇总

转载自 Spring MVC & Boot & Cloud 技术教程汇总昨天我们发布了Java成神之路上的知识汇总,今天继续。 Java成神之路技术整理(长期更新) 以下是Java技术栈微信公众号发布的关于 Spring/ Spring MVC/ Spring Boot/ Spring Cloud 的技术…

group by分组、having() 筛选组的用法

【1】选出 除语文学科外,且学科平均分大于60 的每个学科的最高最低分;

Java成神之路技术整理

转载自 Java成神之路技术整理以下是Java技术栈微信公众号发布的所有关于 Java 的技术干货,会从以下几个方面汇总,本文会长期更新。 Java 基础篇Java 集合篇Java 多线程篇Java JVM篇Java 进阶篇Java 新特性篇Java 工具篇Java 书籍篇 Java基础篇 8张图带你…

RFC+JSF术语

RFC 请求注解(Request For Comments) JSF JavaServer Faces (JSF) is a Java specification for building component-based user interfaces for web applications.

图解 5 种 Join 连接及实战案例!(inner/ left/ right/ full/ cross)

转载自 图解 5 种 Join 连接及实战案例!(inner/ left/ right/ full/ cross) Join 连接在日常开发用得比较多,但大家都搞清楚了它们的使用区别吗??一文带你上车~~ 内连接 inner join 内连接是基于连接谓词…

接口、多态

一.接口 1.接口的定义和使用 接口名:和类名一样,首字母大写 public interface 接口名{//接口中的成员,一般写一些抽象方法 } public class 类名 implements 接口名{//复写接口中所有的抽象方法 } 2.接口的成员热点: &#xff0…

基础笔试编程题(jz)

【1】计算某个单词在某文件中出现的次数. // 计算某个单词在某文件中出现的次数. public class WordCounter {private static int counter;private static String path System.getProperty("user.dir") File.separator "src" File.separator "com…

到底什么是 OAuth 2.0

转载自 到底什么是 OAuth 2.0 ? 一文秒懂!- 理解OAuth 2.0OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。本文对OAuth 2.0的设计思路和运行流程,做一个简明…