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):
解决方法:
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】
【1】What is it? 面向切面编程是什么?
2)切面荔枝:例如,度量(时间,用于度量运行某个代码片需要花费多长时间)是一个常见切面。 要从应用程序生成有用的日志,您必须(通常自由地)在代码中散布信息性消息。 然而,度量是你的类或对象模型真正不应该关注的东西。 毕竟,度量与您的实际应用无关:它不代表客户或帐户,并且不实现业务规则。 它只是正交。
3)横切关注点定义:在AOP中,像度量这样的特征称为横切关注点,因为它是一种“截断”对象模型中多个点但仍然截然不同的行为。作为一种开发方法,AOP建议您抽象和封装横切关注点。
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块中包含时间。
- 如果要扩展此功能以包括方法或失败计数,或者甚至将这些统计信息注册到更复杂的报告机制,则必须再次修改许多不同的文件。
面向方面的编程提供了一种封装这种类型的行为功能的方法。 它允许您添加行为,如度量“围绕”您的代码。 例如,AOP为您提供了程序控制,以指定您希望在执行代码的实际主体之前调用BankAccountDAO来执行度量方面。
【2】在JBoss 切面编程中创建切面
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)切面的抽象型定义:切面是散布在 方法,类,对象层次结构或 整个对象模型中的共同特征;(是一组特征)
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)以上代码块出现了问题
4)aop 是干什么的?
5)如何定义aop中横切关注点的方法 和 指定该横切关注点的应用地点
5.1)定义横切关注点: 将切面代码度量特性封装在自己的Java类中
public class Metrics implements org.jboss.aop.Interceptor public 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(..))")