一、环境与问题

环境

  spring boot的版本是1.2.1.RELEASE、JDK版本是1.7

问题

  ​ A服务 PeopleService 调用B服务 HelloService ,其中B服务的方法 say() 是是一个事物方法,并且B服务实现一个接口 IHelloService 。实际过程中发现A服务无法使用 @autowire 把B服务注入,但是去掉接口 `IHelloService 或者去掉 @Transactional 则可注入B服务,亦或者@Autowired注入的类型使用IHelloService

二、问题思考

​   在解决上面问题时,我们必须要知道spring容器在开启事物的过程中使用的是AOP技术,其实底层是通过代理实现的。在spring在选择代理时默认实现了2中代理方式一种是JDK代理、另外一种是CGLIB代理。其中JDK代理是基于接口,通过接口InvocationHandler实现的,而CGLIB代理是基于类的,通过接口MethodInterceptor 来实现。

三、验证思考

  为了验证我的解决思路是否正确,去官网查看了一下文档

10.5 Using the ProxyFactoryBean to create AOP proxies
   JavaBean properties
   In common with most FactoryBean implementations provided with Spring, the ProxyFactoryBean
class is itself a JavaBean. Its properties are used to:
• Specify the target you want to proxy.
• Specify whether to use CGLIB.

​ 上面这段话的大体意思:一般情况下面我们使用FactoryBean来提供bean,当使用AOP时会使用ProxyFactoryBean来提供bean。我们可以指定目标(即需要代理的对象),也可指定是否使用CGLIB代理。换而言之,spring默认使用的是JDK的代理。

再看一下实际的A服务的bean

果然是如我们猜想的那样使用了JDK代理。

四、解决问题

指定使用CGLIB代理

@Scope(proxyMode=ScopedProxyMode.TARGET_CLASS)

再看一下结果

当我们指定用CGLIB代理之后,发现HelloService 可以被正常进行注入,并且HelloService 也由JDK代理对象变成了CGLIB代理对象。

五、问题深入与扩展

  ​ 随着问题的深入,我们没有解决为什么使用JDK的代理对象不行,而使用CGLIB代理对象却可以?

  不知道大家有没有注意我上面讲过一句话“JDK代理是基于接口...,而CGLIB代理是基于类的...”,问题就出现在这边。下面我把基于JDK和CGLIB的对象的类名、父类名及接口名打印出来:

  HelloService 基于JDK的代理方式:

基于JDK代理的helloService对象的类名$Proxy44,父类是Proxy,接口是IHelloService

  HelloService 基于CGLIB的代理方式:

基于CGLIB代理的helloService对象的类名是HelloService$$EnhancerBySpringCGLIB$$80f67bbd 父类是HelloService

至此我们终于知道了通过@Autowired 注入HelloService 对象时,使用JDK代理时代理对象实现了IHelloService接口,而使用CGLIB代理时代理对象是继承了HelloService

​   spring中的代理的问题告一段落了,孔夫子讲过"举一隅,不以三隅反,则不复也"。那么我们实际项目中还有那些耳熟能详的框架也使用了代理了呢?

​ 在web开发中不知道大家有没有注意到mybatis中只有接口而没有实现类,其实也是使用了JDK的代理。有兴趣的童鞋可以研究一下。

spring中基于JDK和CGLIB代理在项目的应用的更多相关文章

  1. Spring AOP中的JDK和CGLib动态代理哪个效率更高?

    一.背景 今天有小伙伴面试的时候被问到:Spring AOP中JDK 和 CGLib动态代理哪个效率更高? 二.基本概念 首先,我们知道Spring AOP的底层实现有两种方式:一种是JDK动态代理, ...

  2. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

  3. Spring中的JDK动态代理

    Spring中的JDK动态代理 在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层 ...

  4. 基于 JDK 的动态代理机制

    『动态代理』其实源于设计模式中的代理模式,而代理模式就是使用代理对象完成用户请求,屏蔽用户对真实对象的访问. 举个最简单的例子,比如我们想要「FQ」访问国外网站,因为我们并没有墙掉所有国外的 IP,所 ...

  5. Spring中基于xml的AOP

    1.Aop 全程是Aspect Oriented Programming 即面向切面编程,通过预编译方式和运行期动态代理实现程序功能的同一维护的一种技术.Aop是oop的延续,是软件开发中的 一个热点 ...

  6. 基于JDK的动态代理原理分析

    基于JDK的动态代理原理分析 这篇文章解决三个问题: What 动态代理是什么 How 动态代理怎么用 Why 动态代理的原理 动态代理是什么? 动态代理是代理模式的一种具体实现,是指在程序运行期间, ...

  7. 在Spring中使用JDK定时器实现调度任务

    在Spring中使用JDK定时器实现调度任务 作者:chszs,转载需注明.博客主页: http://blog.csdn.net/chszs 本文探讨Spring如何集成JDK的Timer定时器,实现 ...

  8. 【转】在Spring中基于JDBC进行数据访问时怎么控制超时

    http://www.myexception.cn/database/1651797.html 在Spring中基于JDBC进行数据访问时如何控制超时 超时分类 超时根据作用域可做如下层级划分: Tr ...

  9. Spring 框架的概述以及Spring中基于XML的IOC配置

    Spring 框架的概述以及Spring中基于XML的IOC配置 一.简介 Spring的两大核心:IOC(DI)与AOP,IOC是反转控制,DI依赖注入 特点:轻量级.依赖注入.面向切面编程.容器. ...

随机推荐

  1. HTTP请求与接收get/post方式

    //get方式 public string HttpGet(string Url, string postDataStr) { HttpWebRequest request = (HttpWebReq ...

  2. webpack dllPlugin使用(基于vue-cli webpack模板)

    由于本例单入口时打包的文件体积过大,将其分成多入口. 主要涉及到的几个文件为: /index.html, /webpack.dll.config.js, /build/webpack.base.con ...

  3. Vue小项目二手书商城:(一)准备工作、组件和路由

    本项目基于vue2.5.2,与低版本部分不同之处会在(五)参考资料中提出 完整程序:https://github.com/M-M-Monica/bukesi 实现内容: 资源准备(mock数据) 组件 ...

  4. input[type=file]的美化

    __ 一般的选择框在美化过程中会出现各种问题,样式出错,文字无法更改等... 所有随之而生的便是这样的一种修饰方式:[将type=file的input与另一个按钮通过js绑定,这样便可以通过改变另一个 ...

  5. Hadoop之HDFS概述

    一.HDFS产生背景及定义 1.HDFS产生背景 随着数据量越来越大,在一个操作系统存不下所有的数据,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文 ...

  6. 【React】学习之道

    一.工欲善其事必先利其器 - 准备工作 安装vscode:https://code.visualstudio.com/ 安装node.js:https://nodejs.org/en/ 安装gitba ...

  7. 牛客 黑龙江大学程序设计竞赛重现 19-4-25 D

    题意: n项工作 1~n  工时s[i] ~e[i], 工时有覆盖的工作不能被同一台机器同时操作, 问完成所有工作的最少机器数 思路:前缀差分和 e.g. a            2 3 4    ...

  8. es6开发环境搭建,babel 将es6转化成es5

    工欲善其事,必先利其器.所以我们第1节就是搭建一个基本的ES6开发环境.现在的Chrome浏览器已经支持ES6了,但是有些低版本的浏览器还是不支持ES6的语法,这就需要我们把ES6的语法自动的转变成E ...

  9. [Linux] 关闭防火墙以及开放端口

    一. service iptables stop 临时关闭, chkconfig iptables off完全关闭 service iptables status状态, service iptable ...

  10. vue2 作用域插槽slot-scope详解

    插槽分为单个插槽,具名插槽,还有作用域插槽,前两种比较简单这里就不赘述了,今天的重点是讨论作用域插槽. 简单来说,前两种插槽的内容和样式皆由父组件决定,也就是说显示什么内容和怎样显示都由父组件决定: ...