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报错的更多相关文章

  1. 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 ...

  2. org.springframework.beans.factory.BeanNotOfRequiredTypeException

    写一个代码:关于Spring Bean的装配.基于annotation实现的范例代码. 出现了错误: 十一月 14, 2018 4:51:01 下午 org.springframework.conte ...

  3. 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 ...

  4. 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 ...

  5. 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 ...

  6. nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException

    You should autowire interface AbstractManager instead of class MailManager. If you have different im ...

  7. 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 ...

  8. 开发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 ...

  9. 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问题.解决后在此记录一下. 解 ...

随机推荐

  1. jvm的小练习

    代码如下: public static void main(String[] args) { byte[] array= new byte[1024*1024]; array=new byte[102 ...

  2. idea插件 Background Image Plus 随机更换背景图片

    首先在市场搜索: Background Image Plus 设置图片: 在view中,有set 图片,有random图片,有clean图片的 设置就是用set,随便设置个路径. 重点来了,随机更换背 ...

  3. vue进行代码排序

    <template> <div> <div> <h3>排序 </h3> <button @click="orderByAge ...

  4. NCBI SRA数据如何进行md5校验?

    下了一些sra数据库中的公共数据,因为pretech和aspera不稳定,稍微大点的文件经常传断,部分文件我只能通过本地下载再上传. 那么问题来了,sra没有md5校验,我怎么知道我数据的完整性,尤其 ...

  5. Redis总结笔记

    Redis总结笔记 应用场景 缓存--热数据 计算器 队列 位操作 分布式锁与单线程机制 最新列表 排行榜   Maxmemory-policy算法 volatile-lru:使用LRU算法移除key ...

  6. 【7】基于NGS检测体系变异解读和数据库介绍

    目录 解读相关专业术语 体系变异解读规则 体系变异和用药解读流程 主要数据库介绍 解读相关专业术语 2个概念:胚系.体系突变 4种变异类型:SNV.Indel.融合/SV(大的易位/倒位/缺失).CN ...

  7. mysql-select as

    给查询对象起个别名. 把查询对像起个别名的作用. select ID as 用户ID,Name as 用户名 from Table_user

  8. C语言 指针数组指针

    指向指针数组的指针. 1 #include <stdio.h> 2 3 int main(void) 4 { 5 char *pa[4]={"aaaaa"," ...

  9. Markdown-写作必备

    Markdown--入门指南 导语: Markdown 是一种轻量级的「标记语言」,它的优点很多,目前也被越来越多的写作爱好者,撰稿者广泛使用.看到这里请不要被「标记」.「语言」所迷惑,Markdow ...

  10. Navicat连接Linux系统下的Mysql数据库

    1 . 进入Linux机器 , 登录并进入mysql如果没有安装mysql,参照 https://blog.csdn.net/weixin_35353187/article/details/81712 ...