- 浏览: 5079703 次
- 性别:
- 来自: 南京
-
文章分类
- 全部博客 (2844)
- java (1094)
- hadoop (37)
- jvm (39)
- hbase (11)
- sql (25)
- 异常 (83)
- div css (6)
- 数据库 (95)
- 有趣的code (15)
- struts2 (6)
- spring (124)
- js (44)
- 算法 (65)
- linux (36)
- hibernate (7)
- 中间件 (78)
- 设计模式 (2)
- 架构 (275)
- 操作系统 (91)
- maven (35)
- tapestry (1)
- mybatis (9)
- MQ (101)
- zookeeper (18)
- 搜索引擎,爬虫 (208)
- 分布式计算 (45)
- c# (7)
- 抓包 (28)
- 开源框架 (45)
- 虚拟化 (12)
- mongodb (15)
- 计算机网络 (2)
- 缓存 (97)
- memcached (6)
- 分布式存储 (13)
- scala (5)
- 分词器 (24)
- spark (104)
- 工具 (23)
- netty (5)
- Mahout (6)
- neo4j (6)
- dubbo (36)
- canal (3)
- Hive (10)
- Vert.x (3)
- docker (115)
- 分布式追踪 (2)
- spring boot (5)
- 微服务 (56)
- 淘客 (5)
- mesos (67)
- php (3)
- etcd (2)
- jenkins (4)
- nginx (7)
- 区块链 (1)
- Kubernetes (92)
- 驾照 (1)
- 深度学习 (15)
- JGroups (1)
- 安全 (5)
- 测试 (16)
- 股票 (1)
- Android (2)
- 房产 (1)
- 运维 (6)
- 网关 (3)
最新评论
-
明兜3号:
部署落地+业务迁移 玩转k8s进阶与企业级实践技能(又名:Ku ...
Kubernetes系统常见运维技巧 -
q328965539:
牛掰啊 资料收集的很全面
HDFS小文件处理解决方案总结+facebook(HayStack) + 淘宝(TFS) -
guichou:
fluent挂载了/var/lib/kubelet/pods目 ...
kubernetes上部署Fluentd+Elasticsearch+kibana日志收集系统 -
xu982604405:
System.setProperty("java.r ...
jmx rmi 穿越防火墙问题及jmxmp的替代方案 -
大漠小帆:
麻烦问下,“获取每个Item相似性最高的前N个Item”,这个 ...
协同过滤推荐算法在MapReduce与Spark上实现对比
在spring中有两种产生代理对象的方式:
AopProxy的子类:Cglib2AopProxy和JdkDynamicAopProxy。
1. Jdk主要是:Proxy.newProxyInstance(classLoader, proxiedInterfaces, InvocationHandler);
2. Cglib则是通过Enhancer类来实现的。
它们有个相同点就是都有一个回调方法。我们可以在回调方法中对目标方法进行增强。
JDK代理对象的回调
1. public Object invoke(Object proxy, Method method, Object[]
2. args) throws Throwable {
3. MethodInvocation invocation = null;
4. Object oldProxy = null;
5. boolean setProxyContext = false;
6. TargetSource targetSource =
7. this.advised.targetSource;
8. Class targetClass = null;
9. Object target = null;
10. try {
11. if (!this.equalsDefined &&
12. AopUtils.isEqualsMethod(method)) {
13. // The target does not implement the
14. equals(Object) method itself.
15. return equals(args[0]);
16. }
17. if (!this.hashCodeDefined &&
18. AopUtils.isHashCodeMethod(method)) {
19. // The target does not implement the
20. hashCode() method itself.
21. return hashCode();
22. }
23. if (!this.advised.opaque &&
24. method.getDeclaringClass().isInterface() &&
25.
26. method.getDeclaringClass().isAssignableFrom(Advised.class))
27. {
28. // Service invocations on
29. ProxyConfig with the proxy config...
30. return
31. AopUtils.invokeJoinpointUsingReflection(this.advised,
32. method, args);
33. }
34. Object retVal = null;
35. if (this.advised.exposeProxy) {
36. // Make invocation available if
37. necessary.
38. oldProxy =
39. AopContext.setCurrentProxy(proxy);
40. setProxyContext = true;
41. }
42. /**
43. * May be null. Get as late as possible to
44. minimize the time we "own" the
45. * target, in case it comes from a pool.
46. */
47. //得到目标对象的地方。
48. target = targetSource.getTarget();
49. if (target != null) {
50. targetClass = target.getClass();
51. }
52. // Get the interception chain for this
53. method.
54. // 这里获得定义好的拦截器链。
55. List chain =
56. this.advised.getInterceptorsAndDynamicInterception
57. Advice(method, targetClass);
58. /**
59. * Check whether we have any advice. If we
60. don't, we can fallback on
61. * direct reflective invocation of the
62. target, and avoid creating a MethodInvocation.
63. */
64.
65. //
66. 如果没有设定拦截器,那么我们就直接调用target的对应方法。
67. if (chain.isEmpty()) {
68. /**
69. * We can skip creating a
70. MethodInvocation: just invoke the target directly
71. * Note that the final invoker must
72. be an InvokerInterceptor so we
73. * know it does nothing but a
74. reflective operation on the target, and no hot
75. * swapping or fancy proxying.
76. */
77. retVal =
78. AopUtils.invokeJoinpointUsingReflection(target, method,
79. args);
80. }
81. else {
82. // We need to create a method
83. invocation...
84. /**
85. *
86. 如果有拦截器的设定,那么需要调用拦截器之后才调用目标对象的相
87. 应方法,
88. *
89. 通过构造一个ReflectiveMethodInvocation来实现,下面我们会看
90. *
91. 这个ReflectiveMethodInvocation类的具体实现。
92. */
93. invocation = new
94. ReflectiveMethodInvocation(proxy, target, method,
95. args, targetClass, chain);
96. // Proceed to the joinpoint through
97. the interceptor chain.
98. //沿着拦截器链继续前进。
99. retVal = invocation.proceed();
100. }
101.
102. // Massage return value if necessary.
103. if (retVal != null && retVal == target &&
104. method.getReturnType().
105. isInstance(Proxy) &&
106. !RawTargetAccess.class.isAssignableFrom
107. (method.getDeclaringClass())) {
108. /**
109. * Special case: it returned "this"
110. and the return type of the method
111. * is type-compatible. Note that we
112. can't help if the target sets
113. * a reference to itself in another
114. returned object.
115. */
116. retVal = Proxy;
117. }
118. return retVal;
119. }
120. finally {
121. if (target != null &&
122. !targetSource.isStatic()) {
123. // Must have come from TargetSource.
124. targetSource.releaseTarget(target);
125. }
126. if (setProxyContext) {
127. // Restore old proxy.
128.
129. AopContext.setCurrentProxy(oldProxy);
130. }
131. }
132. }
Cglib代理对象的回调方法:
1. public Object intercept(Object proxy, Method method,
2. Object[] args, MethodProxy
3. methodProxy) throws Throwable {
4. Object oldProxy = null;
5. boolean setProxyContext = false;
6. Class targetClass = null;
7. Object target = null;
8. try {
9. if (this.advised.exposeProxy) {
10. // Make invocation available if
11. necessary.
12. oldProxy =
13. AopContext.setCurrentProxy(proxy);
14. setProxyContext = true;
15. }
16. /**
17. * May be
null
. Get as late as
18. possible to minimize the time we
19. * "own" the target, in case it comes from a
20. pool.
21. */
22. target = getTarget();
23. if (target != null) {
24. targetClass = target.getClass();
25. }
26. //从advised中取得配置好的AOP通知。
27. List chain =
28. this.advised.getInterceptorsAndDynamicInterceptionAdvice
29. (method, targetClass);
30. Object retVal = null;
31. /**
32. * Check whether we only have one
33. InvokerInterceptor: that is,
34. * no real advice, but just reflective
35. invocation of the target.
36. */
37. //
38. 如果没有AOP通知配置,那么直接调用target对象的调用方法。
39. if (chain.isEmpty() &&
40. Modifier.isPublic(method.getModifiers())) {
41. /**
42. * We can skip creating a
43. MethodInvocation: just invoke the target directly.
44. * Note that the final invoker must
45. be an InvokerInterceptor, so we know
46. * it does nothing but a reflective
47. operation on the target, and no hot
48. * swapping or fancy proxying.
49. */
50. retVal = methodProxy.invoke(target,
51. args);
52. }
53. else {
54.
55. //通过CglibMethodInvocation来启动advice通知。
56. retVal = new
57. CglibMethodInvocation(proxy, target, method, args,
58. targetClass, chain, methodProxy).proceed();
59. }
60. retVal = massageReturnTypeIfNecessary(proxy,
61. target, method, retVal);
62. return retVal;
63. }
64. finally {
65. if (target != null) {
66. releaseTarget(target);
67. }
68. if (setProxyContext) {
69. // Restore old proxy.
70.
71. AopContext.setCurrentProxy(oldProxy);
72. }
73. }
74. }
在调用代理目标对象的方法时;都对方法进行了增强。
75. //从advised中取得配置好的AOP通知。
76. List chain =
77. this.advised.getInterceptorsAndDynamicInterceptionAdvice
(method, targetClass);
在这里可以设置不同的拦截器进行不同的业务处理。比如记录日志,事物的开启…
这就是Aop的核心。具体是由相关的拦截器完成的。
在jdk,cglib代理类中都有一个拦截链处理器,它们分别是
JDK代理类拦截链处理器:
133. 这个ReflectiveMethodInvocation类的具体实现。
134. */
135. ReflectiveMethodInvocation invocation = new
136. ReflectiveMethodInvocation(proxy, target, method,
137. args, targetClass, chain);
138. //沿着拦截器链继续前进。
retVal = invocation.proceed();
CGLIB代理类拦截链处理器:
78. //通过CglibMethodInvocation来启动advice通知。
79. retVal = new
80. CglibMethodInvocation(proxy, target, method, args,
81. targetClass, chain, methodProxy).proceed();
82. }
83. retVal = massageReturnTypeIfNecessary(proxy,
84. target, method, retVal);
JDK代理类拦截链处理器的proceed方法:
1. public Object proceed() throws Throwable {
2. // We start with an index of -1 and increment
3. early.
4. /**
5. *如果拦截器链中的拦截器迭代调用完毕,这里开始调用tar
6. get的函数,
7. *这个函数是通过反射机制完成的,具体实现在:AopUtils.
8. invokeJoinpointUsingReflection方法里面。
9. */
10. if (this.currentInterceptorIndex ==
11. this.interceptorsAndDynamicMethod
12. Matchers.size() - 1) {
13. return invokeJoinpoint();
14. }
15. //这里沿着定义好的
16. interceptorOrInterceptionAdvice链进行处理。
17. Object interceptorOrInterceptionAdvice =
18. this.interceptorsAndDynamicMethodMatchers.get(++this
19. .currentInterceptor
20. Index);
21. if (interceptorOrInterceptionAdvice instanceof
22. InterceptorAndDynamic
23. MethodMatcher) {
24. /**
25. * Evaluate dynamic method matcher here:
26. static part will already have
27. * been evaluated and found to match.
28. */
29. /**
30.
31. *这里对拦截器进行动态匹配的判断,还记得我们前面分析的pointcu
32. t吗?
33.
34. *这里是触发进行匹配的地方,如果和定义的pointcut匹配,那么这
35. 个advice将会得到执行。
36. */
37. InterceptorAndDynamicMethodMatcher dm =
38. (InterceptorAndDynamicMethodMatcher)
39. interceptorOrInterceptionAdvice;
40. if (dm.methodMatcher.matches(this.method,
41. this.targetClass, this.arguments)) {
42. return dm.interceptor.invoke(this);
43. }
44. else {
45. // Dynamic matching failed.
46. // Skip this interceptor and invoke
47. the next in the chain.
48. //
49. 如果不匹配,那么proceed会被递归调用,直到所有的拦截器都被运
50. 行过为止。
51. return proceed();
52. }
53. }
发表评论
-
spring session序列化问题排查
2017-12-01 19:07 6323严重: Servlet.service() for ser ... -
spring mvc统一异常处理(@ControllerAdvice + @ExceptionHandler)
2017-12-01 17:09 3032spring 封装了非常强大的异常处理机制。本文选取@Co ... -
springboot注解
2017-12-01 09:44 1053@RestController和@RequestMappin ... -
Spring 4 xml 注解配置谅解
2017-12-01 09:39 1154《Spring in Action》4th E ... -
利用junit对springMVC的Controller进行测试
2017-11-30 16:26 1480平时对junit测试service/D ... -
spring cloud config实现datasource的热部署
2017-11-21 16:44 1657关于spring cloud config的基本使用,前面的 ... -
Spring+MyBatis实现数据库读写分离方案
2017-11-20 17:15 1147百度关键词:spring mybatis 多数据源 读写分离 ... -
spring session 退出登录 清理session
2017-11-10 09:26 6490/** * Allows creating an ... -
spring http session 监听 创建 失效session
2017-11-15 09:35 4902一.流程概述 主要是通过扩展ServletRequest ... -
spring session spring:session:sessions:expires 源码跟踪
2017-11-14 09:37 1548/** * Saves any attribut ... -
spring session 考虑问题解答
2017-11-09 09:50 681相关问题 2.Redis容量考虑,由于spring see ... -
spring 获取bean 测试
2017-11-09 09:51 702package com.jayway.springsess ... -
spring父子容器与读取properties文件
2017-11-09 09:51 847读取properties文件中的内容,可以使用@Value ... -
Spring在代码中获取bean的几种方式
2017-11-08 09:46 1258方法一:在初始化时保存ApplicationContext对 ... -
Spring中DispacherServlet、WebApplicationContext、ServletContext的关系
2017-11-08 09:41 848解释一: 要想很好理解这三个上下文的关系,需 ... -
Spring以及SPringmvc相关问题: ServletContext -父子容器
2017-11-08 09:41 644总结如下: 明确了Servlet规范中Servl ... -
DelegatingFilterProxy
2017-11-08 09:48 1240摘要: 配置过滤器代理类,通过spring配置的bean来 ... -
DelegatingFilterProxy-api
2017-11-09 09:51 587为什么用DelegatingFilterProxy ... -
spring的启动过程——spring和springMVC父子容器的原理
2017-11-15 09:29 746要想很好理解这三个上下文的关系,需要先熟悉spri ... -
spring中bean被多次实例化问题
2017-11-13 09:33 52611. 描述 spring中提供了两种主要方式实例化bea ...
相关推荐
### Spring源码解析知识点 #### 一、Spring IoC 容器详解 ##### 1. BeanFactory —— 最...掌握Spring的源码解析不仅可以帮助开发者更好地理解和使用Spring框架,还能提高解决问题的能力,增强软件开发的整体质量。
在Spring5中,DI仍然是核心设计模式,它使得对象之间的依赖关系得以解耦,增强了代码的可测试性和可维护性。Tom老师的文档会详细阐述IoC容器是如何实现DI的,包括Bean的生命周期管理、自动装配以及各种类型的Bean...
6. **Spring源码分析**:通过阅读源码,理解Spring框架的工作原理,增强对框架的深入理解。 接下来,我们转向MyBatis,这是一个轻量级的持久层框架,它提供了灵活的SQL映射机制,使得数据库操作变得简单。"MyBatis3...
《Spring源码深入解析》是一本深度探讨Spring框架核心机制的文档,主要针对Spring5版本...文档《Spring源码解析-tom.docx》应包含了上述各方面的详细解读,对于希望深入了解Spring的开发者来说,是一份宝贵的参考资料。
`ProxyFactoryBean`和`AspectJAutoProxyCreator`是AOP实现的两个关键类,它们生成代理对象并执行切面逻辑。 在Spring MVC和AOP的基础上,Spring还支持与ORM框架的集成,如Hibernate。Spring通过`HibernateTemplate`...
在运行时,Spring会创建一个代理对象,这个代理对象不仅包含了目标对象的所有行为,还额外实现了`SecuredInterface`。 **使用场景** 引入在以下场景中尤其有用: 1. **安全性增强** - 添加认证和授权功能,如`...
Spring AOP通过动态代理(JDK Proxy或CGLIB)创建目标对象的代理,实现切面的织入。Pointcut定义切入点,Advice定义增强处理,Advisor结合两者,Aspect则封装了多个Advisor。 6. **Spring 声明式事务处理**:基于...
在Spring AOP执行过程中,当调用被代理对象的方法时,实际上会触发AOP代理的拦截逻辑,执行相应的通知,并在适当的时候调用实际的目标方法。 总的来说,Spring AOP通过动态代理机制,实现了对目标对象的透明拦截,...
此外,还可以通过expose-proxy属性来控制是否将代理对象暴露到ThreadLocal中,以便在目标类的内部方法中可以方便地访问到代理对象。 在Spring AOP中,还可以通过实现BeanPostProcessor接口来自定义bean的创建过程,...
《Spring框架4.2.4源码解析》 Spring框架是Java领域中广泛使用的轻量级开源框架,它以其模块化、松耦合的设计理念,为开发者提供了强大的企业级应用开发支持。本篇将深入探讨Spring 4.2.4版本的源码,通过分析各个...
Spring 4.3对MVC进行了优化,包括更好的类型安全的模型绑定、增强的异常处理和视图解析。`@RequestMapping`、`@GetMapping`、`@PostMapping`等注解用于映射HTTP请求到处理方法。`ModelAndView`或`Model`接口用于向...
"Spring CGLlB动态代理实现过程解析" Spring CGLIB动态代理是Spring框架中的一种动态代理机制,它通过CGLIB(Code Generation Library)生成代理类来实现动态代理。CGLIB是一个高性能的开源代码生成包,能够在运行...
### Dubbo源码解析2 #### 一、源码阅读路径 在开始深入解析Dubbo源码之前,首先需要明确的是,Dubbo虽然代码量不算庞大,但是它涉及的技术领域非常广泛,对于初学者来说,可能需要具备一定的前置知识才能更好地...
《Spring源码解析》系列文章深入探讨了Spring框架的核心组件和工作原理,为读者提供了丰富的技术洞察。以下是对这些主题的详细解读: 1. **Spring MVC**:Spring MVC是Spring框架的一部分,它提供了构建Web应用程序...
《Spring框架源码解析——深度探索spring-demo》 在IT领域,Spring框架是Java开发者最为广泛应用的轻量级框架之一,其强大的功能和灵活的设计深受赞誉。本文将深入探讨"spring-demo:spring原始解析"这一主题,带领...
再比如`AOPProxy`和`Advised`,它们是实现AOP的关键组件,用于创建代理对象并管理增强(advice)。 深入学习Spring源码,不仅能够帮助我们理解其工作原理,还能提升我们在实际项目中的问题排查能力。例如,当我们...
接下来我将详细介绍Spring框架中几个核心模块的源码解析。 首先,Spring的依赖注入(DI)是Spring框架的核心特性之一,它通过容器来管理对象之间的依赖关系。Spring容器在创建对象时,会自动注入这些对象所需的依赖...
Spring AOP主要基于动态代理技术实现,通过创建代理对象来拦截目标方法调用,从而实现对目标方法的增强。 - **代理模式**:Spring AOP支持两种类型的代理:JDK动态代理和CGLIB代理。 - **JDK动态代理**:适用于...
AOP通过动态代理技术(JDK Proxy或CGLIB)实现,可以在不修改原有代码的情况下,插入额外的功能,增强了代码的可扩展性。 3. **Bean工厂与ApplicationContext** Spring的Bean工厂是对象管理的基础,它负责创建、...