Spring5 AOP编程:关于org.springframework.beans.factory.BeanNotOfRequiredTypeException报错
Spring5 AOP编程:关于org.springframework.beans.factory.BeanNotOfRequiredTypeException报错
先上错误详细信息:

org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'bookDaoImpl' is expected to be of type 'com.atguigu.dao.BookDaoImpl' but was actually of type 'com.sun.proxy.$Proxy19'
直译过来大概意思是说:这个叫做bookDaoImpl的Bean,应该是BookDaoImpl类型,然而现在是com.sun.proxy.$Proxy19类型
疑惑????查看对应源码:下图第七行报错!
@Test
public void addTest() { // 在数据库中,添加 现代光电测试
// 1. Spring读取配置文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
// 2. 获取BookDaoImpl对象 (错误行)
BookDaoImpl bookDaoImpl = context.getBean("bookDaoImpl", BookDaoImpl.class);
// 3. 测试方法
bookDaoImpl.add(new Book(18, "现代光电测试", 120, 4));
}
从这段代码上,bookDaoImpl确实应该是BookDaoImpl类型,按理说代码没写错,为啥getBean()方法返回的不是BookDaoImpl类型。直觉告诉我,应该是增强类代码出现问题,上增强类代码:
@Service // 创建对象
@Aspect // 这是一个代理对象
public class BookProxy { // 增强类
@Before(value = "execution(* com.atguigu.dao.BookDaoImpl.add(..))") // 注意参数 .. 别忘了
@Order(1)
public void addBefore() {
System.out.println("Proxy01:添加方法准备就绪!");
}
@Before(value = "execution(* com.atguigu.dao.BookDaoImpl.add(..))")
@Order(2)
public void addBefore01() {
System.out.println("Proxy02:执行!");
}
}
检查代码之后,发现增强类也没问题啊............
没想明白
最后求助百度,发现有人说这个错误可能是因为JDK动态代理不支持类注入导致的。
检查被增强类代码,发现确实如此,一切的源头:下图第六行代码,JdbcTemplate已经是一个类对象,使用JDK动态代理无法进行注入类对象的操作。
原增强类代码:
@Service(value = "bookDaoImpl")
public class BookDaoImpl implements BookDao{
// 注入JdbcTemplate
@Autowired
private JdbcTemplate jdbcTemplate; // JDK动态代理并不能进行类的注入!!
.......
}
因为JDK动态代理只支持创建接口实现类代理对象,从而增强类的方法。**
于是,解决方案如下:
新建一个被增强类,命名为BookServiceProxy:其中BookDao是接口,也就是原被增强类BookDaoImpl实现的接口。
解决方案的核心思想:通过一个类封装接口对象,并在这个类中的各个方法中,调用这个接口对应的方法,然后通过增强这个类的各个方法,从而达到 对 实现这个接口的类 的方法 的增强(有点绕,相当于套娃)。
至于为什么这么做?是因为JDK动态代理的原理,就是通过创建接口的另一个实现类,被将其作为代理对象,然后在类代理对象中,编写增强逻辑,从而对原实现类的方法进行增强。
@Service(value = "bookServiceProxy")
public class BookServiceProxy {
// 注入BookDao
@Autowired
private BookDao bookDao; // 被增强类所实现的BookDao接口,因为是接口类型,能够进行注入!
// add
public void addBook(Book book) { // Book 为 entity
bookDao.add(book);
}
// update
public void updateBook(int classhours, String name) {
bookDao.update(classhours, name);
}
// delete
public void deleteBook(String name) {
bookDao.delete(name);
}
}
重写编写增强类代码,对新的被增强类BookServiceProxy进行切面操作。
@Service // 创建对象
@Aspect // 这是一个代理对象
public class BookProxy { // 增强类
@Before(value = "execution(* com.atguigu.service.BookServiceProxy.addBook(..))") // 注意参数 .. 别忘了
@Order(1)
public void addBefore() {
System.out.println("Proxy01:添加方法准备就绪!");
}
@Before(value = "execution(* com.atguigu.service.BookServiceProxy.addBook(..))")
@Order(2)
public void addBefore01() {
System.out.println("Proxy02:执行!");
}
}
测试代码:
@Test
public void BookServiceProxyTest() {
// 1. Spring读取配置文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
// 2. 获取BookDaoImpl对象
BookServiceProxy bookServiceProxy = context.getBean("bookServiceProxy", BookServiceProxy.class);
// 3. 测试方法
bookServiceProxy.addBook(new Book(18, "现代光电测试", 120, 4));
}
运行结果:
Proxy01:添加方法准备就绪!
Proxy02:执行!
10月 15, 2021 9:50:01 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info
信息: {dataSource-1} inited
插入操作执行成功!Process finished with exit code 0
Spring5 AOP编程:关于org.springframework.beans.factory.BeanNotOfRequiredTypeException报错的更多相关文章
- Spring错误之org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'bookService' is expected to be of type 'pw.fengya.tx.BookService' but was actually of type 'com.sun.proxy.$Proxy1
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cas ...
- org.springframework.beans.factory.BeanNotOfRequiredTypeException
写一个代码:关于Spring Bean的装配.基于annotation实现的范例代码. 出现了错误: 十一月 14, 2018 4:51:01 下午 org.springframework.conte ...
- Spring AOP 报错org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'XXXXXX' defined in class path resource..........
完整报错如下: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'befo ...
- Spring AOP:Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException
1 报错 Exception encountered during context initialization - cancelling refresh attempt: org.springfra ...
- Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener org.springframework.beans.factory.BeanCreationException:
严重: Exception sending context initialized event to listener instance of class org.springframework.we ...
- nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException
You should autowire interface AbstractManager instead of class MailManager. If you have different im ...
- ssh整合报错严重: Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxx'
错误描述:eclipse整合ssh的时候 报不能创建名字为xxx的对象 信息: Destroying singletons in org.springframework.beans.factory.s ...
- 开发Spring过程中几个常见异常(二):Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'a' define
本异常是小编在运行自己另外一篇博文中的例子时遇到的.(附博文:http://www.cnblogs.com/dudududu/p/8482487.html) 完整异常信息: 警告: Exception ...
- Caused by:org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type "" available: expected at least 1 bean which qualifies as autowire candidate
项目使用spring, mybatis.因为分了多个模块,所以会这个模块引用了其它模块的现在,结果使用Junit测试的时候发现有两个模块不能自动注入dao和service问题.解决后在此记录一下. 解 ...
随机推荐
- java Scanner类与String类
Scanner类的使用: 导入Scanner包,new Scanner对象,记得调用System.in参数,调用对应next方法实现键盘录入. import java.util.Arrays; i ...
- CF1553 部分题解
CF1553D Backspace 题目传送门. 题意简述:给定 \(s,t\),现在要依次输入 \(s\) 中的字符.对于每个字符 \(s_i\),你可以选择输入 \(s_i\) 或者使用退格键,判 ...
- 代码整洁之道Clean Code笔记
@ 目录 第 1 章 Clean Code 整洁代码(3星) ?为什么要整洁的代码 ?什么叫做整洁代码 第 2 章 Meaningful Names 有意义的命名(3星) 第 3 章 Function ...
- arm三大编译器的不同选择编译
ARM 系列目前支持三大主流的工具链,即ARM RealView (armcc), IAR EWARM (iccarm), and GNU Compiler Collection (gcc). ...
- svn简单上传下载文件命令
上传命令: svn import 本地文件或目录 远程服务端目录 --username '用户名' --password '密码' -m '添加描述(可为空)' 下载命令: svn export 远程 ...
- Splay(伸展树)/HDU6873
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6873 题目大意 给定一组 \(n\) 列的方块,每列方块数 \(b_i\) ,现有 \(q\) 次操作 ...
- linux系统中上传文件与下载文件的方式
方式一:FileZilla 使用FileZilla第三方工具 绿色版直接打开exe文件即可 主机:连接的linux服务器的IP地址 用户名:登录的用户名 密码:登录密码 端口:默认使用22 左边是自己 ...
- 同步阻塞IO模型
同步阻塞IO模型 有上篇IO模型中的,同步阻塞IO模型,我们能够知道,用户线程发起请求后就一直阻塞的等待 内核完成准备数据.数据拷贝的工作.并且返回成功的指示. 实现 使用java来实现同步阻塞IO模 ...
- LeetCode398-随机数索引
原题链接:[398. 随机数索引]:https://leetcode-cn.com/problems/random-pick-index/ 题目描述: 给定一个可能含有重复元素的整数数组,要求随机输出 ...
- SpringBoot让测试类飞起来的方法
单元测试是项目开发中必不可少的一环,在 SpringBoot 的项目中,我们用 @SpringBootTest 注解来标注一个测试类,在测试类中注入这个接口的实现类之后对每个方法进行单独测试. 比如下 ...