### 从JVM看aop
#### 1. Java程序运行在JVM中的特征
当我们在某个类Foo中写好了一个main()方法,然后执行java Foo,你的Java程序之旅就开启了,如下:
```java
public class Foo {
public static void main(String[] args) {
// your codes begins here
}
}
```
那么在这个执行的过程中,JVM都为你干了什么呢?
当你执行java Foo 的时候,JVM会创建一个主线程main,这个主线程以上述的main()方法作为入口,开始执行你的代码。每一个线程在内存中都会维护一个属于自己的栈(Stack),记录着整个程序执行的过程。栈里的每一个元素称为栈帧(Stack Frame),栈帧表示着某个方法调用,会记录方法调用的信息;实际上我们在代码中调用一个方法的时候,在内存中就对应着一个栈帧的入栈和出栈。
在某个特定的时间点,一个Main线程内的栈会呈现如下图所示的情况:
![image.png](../image/0001.png)
#### 2. Java程序执行流 【了解AOP、连接点(Join Point)、切入点(point cut) 的概念 】
如果从虚拟机线程栈的角度考虑Java程序执行的话,那么,你会发现,真个程序运行的过程就是方法调用的过程。我们按照方法执行的顺序,将方法调用排成一串,这样就构成了Java程序流。
我们将上述的线程栈里的方法调用按照执行流排列,会有如下类似的图:
![image.png](../image/0002.png)
基于时间序列,我们可以将方法调用排成一条线。而每个方法调用则可以看成Java执行流中的一个节点。这个节点在AOP的术语中,被称为Join Point,即连接点。 一个Java程序的运行的过程,就是若干个连接点连接起来依次执行的过程。
在我们正常的面向对象的思维中, 我们考虑的是如何按照时间序列通过方法调用来实现我们的业务逻辑。那么,什么是AOP(即面向切面的编程)呢?
通常面向对象的程序,代码都是按照时间序列纵向展开的,而他们都有一个共性:即都是已方法调用作为基本执行单位展开的。 将方法调用当做一个连接点,那么由连接点串起来的程序执行流就是整个程序的执行过程。
`AOP(Aspect Oriented Programming)则是从另外一个角度来考虑整个程序的,AOP将每一个方法调用,即连接点作为编程的入口,针对方法调用进行编程。从执行的逻辑上来看,相当于在之前纵向的按照时间轴执行的程序横向切入。相当于将之前的程序横向切割成若干的面,即Aspect.每个面被称为切面。`
所以,根据我的理解,AOP本质上是针对方法调用的编程思路。
![image.png](../image/0003.png)
既然AOP是针对切面进行的编程的,那么,你需要选择哪些切面(即 连接点Joint Point)作为你的编程对象呢?
因为切面本质上是每一个方法调用,选择切面的过程实际上就是选择方法的过程。那么,被选择的切面(Aspect)在AOP术语里被称为切入点(Point Cut). 切入点实际上也是从所有的连接点(Join point)挑选自己感兴趣的连接点的过程。
![image.png](../image/0004.png)
既然AOP是针对方法调用(连接点)的编程, 现在又选取了你感兴趣的自己感兴趣的链接点---切入点(Point Cut)了,那么,AOP能对它做什么类型的编程呢?AOP能做什么呢?
了解这个之前,我们先要知道一个非常重要的问题: 既然AOP是对方法调用进行的编程,那么,AOP如何捕获方法调用的呢? 弄清楚这个问题,你不得不了解设计模式中的代理模式了。下面我们先来了解一下引入了代理模式的Java程序执行流是什么样子的。
#### 3. 引入了代理模式的Java程序执行流(AOP实现的机制)
我们假设在我们的Java代码里,都为实例对象通过代理模式创建了代理对象,访问这些实例对象必须要通过代理,那么,加入了proxy对象的Java程序执行流会变得稍微复杂起来。
我们来看下加入了proxy对象后,Java程序执行流的示意图:
![image.png](../image/0005.png)
加入了代理模式的Java程序执行流,使得所有的方法调用都经过了代理对象。对于Spring AOP框架而言,它负责控制着真个容器内部的代理对象。当我们调用了某一个实例对象的任何一个非final的public方法时,整个Spring框架都会知晓。
此时的SpringAOP框架在某种程度上扮演着一个上帝的角色:它知道你在这个框架内所做的任何操作,你对每一个实例对象的非final的public方法调用都可以被框架察觉到!
![image.png](../image/0006.png)
#### 4. Spring AOP的工作原理
前面已经介绍了AOP编程首先要选择它感兴趣的连接点----即切入点(Point cut),那么,AOP能对切入点做什么样的编程呢? 我们先将代理模式下的某个连接点细化,你会看到如下这个示意图所表示的过程:
![image.png](../image/0007.png)
![image.png](../image/0008.png)
![image.png](../image/0009.png)
#### 5、Spring AOP的核心---ProxyFactoryBean
*ProxyFactoryBean提供了如下信息:*
1). Proxy应该感兴趣的Adivce列表;
2). 真正的实例对象引用ticketService;
3).告诉ProxyFactoryBean使用基于接口实现的JDK动态代理机制实现proxy:
4). Proxy应该具备的Interface接口:TicketService;
根据这些信息,ProxyFactoryBean就能给我们提供我们想要的Proxy对象了!那么,ProxyFactoryBean帮我们做了什么?
![image.png](../image/0010.png)
Spring 使用工厂Bean模式创建每一个Proxy,对应每一个不同的Class类型,在Spring中都会有一个相对应的ProxyFactoryBean. 以下是ProxyFactoryBean的类图。
![image.png](../image/0011.png)
如上所示,对于生成Proxy的工厂Bean而言,它要知道对其感兴趣的Advice信息,而这类的信息,被维护到Advised中。Advised可以根据特定的类名和方法名返回对应的AdviceChain,用以表示需要执行的Advice串。
#### 6、基于JDK面向接口的动态代理JdkDynamicAopProxy生成代理对象
JdkDynamicAopProxy类实现了AopProxy,能够返回Proxy,并且,其自身也实现了InvocationHandler角色。也就是说,当我们使用proxy时,我们对proxy对象调用的方法,都最终被转到这个类的invoke()方法中。
```java
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
//省略若干...
/** Proxy的配置信息,这里主要提供Advisor列表,并用于返回AdviceChain */
private final AdvisedSupport advised;
/**
* Construct a new JdkDynamicAopProxy for the given AOP configuration.
* @param config the AOP configuration as AdvisedSupport object
* @throws AopConfigException if the config is invalid. We try to throw an informative
* exception in this case, rather than let a mysterious failure happen later.
*/
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
}
@Override
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
//返回代理实例对象
@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//这里的InvocationHandler设置成了当前实例对象,即对这个proxy调用�
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
Java前后开发面试题,大厂进阶之路,基于JavaGuide、Cyc大佬、牛客上的面经及王道考研相关视频,并改进了其中说法矛盾或含糊之处。 包含计算机网络知识、JavaSE、JVM、Spring、Springboot、SpringCloud、Mybatis、多线程并发、netty、MySQL、MongoDB、Elasticsearch、Redis、HBASE
资源推荐
资源详情
资源评论
收起资源包目录
java进阶,包含 常用设计模式、线程和并发、spring核心代码 (834个子文件)
access_log.2018-06-05 306B
access_log.2019-03-21 96B
index.adoc 211B
manual_content1.adoc 102B
manual_content2.adoc 57B
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
mvnw.cmd 6KB
spring.factories 144B
spring.factories 124B
.gitignore 333B
.gitignore 303B
.gitignore 299B
.gitignore 277B
.gitignore 277B
.gitignore 277B
.gitignore 277B
.gitignore 277B
.gitignore 277B
.gitignore 277B
.gitignore 277B
.gitignore 277B
.gitignore 277B
.gitignore 277B
.gitignore 269B
.gitignore 269B
.gitignore 269B
.gitignore 269B
.gitignore 269B
.gitignore 269B
.gitignore 269B
.gitignore 269B
.gitignore 269B
.gitignore 269B
.gitignore 269B
.gitignore 269B
index.html 539B
index.html 164B
hello-world.html 143B
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
maven-wrapper.jar 47KB
MyFrameworkServlet.java 20KB
MyRequestMappingHandlerAdapter.java 16KB
MyRequestMappingInfo.java 16KB
MyAbstractHandlerMethodMapping.java 14KB
MyRedirectView.java 13KB
CourseExample.java 13KB
MyDispatcherServlet.java 12KB
UserExample.java 11KB
UserExample.java 11KB
UserExample.java 11KB
MyServletInvocableHandlerMethod.java 8KB
MyRequestContext.java 8KB
MyUrlBasedViewResolver.java 7KB
MyServletModelAttributeMethodProcessor.java 7KB
MyWebContentGenerator.java 6KB
共 834 条
- 1
- 2
- 3
- 4
- 5
- 6
- 9
资源评论
极致人生-010
- 粉丝: 2909
- 资源: 2826
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功