Spring AOP获取不了增强类(额外方法)和无法通过getBean()获取对象

今天在学习AOP发现一个小问题

Spring AOP获取不了额外方法,左思右想发现是接口上出了问题

先上代码

获取不了增强类

UserService接口

public interface UserService {
public void register(User user); public Boolean login(String name, String password);
}

接口实现UserServiceImpl(原始方法)

这是出问题的地方

import org.User;
import org.aopalliance.aop.Advice;
public class UserServiceImpl implements UserService , Advice{ @Override
public void register(User user) {
System.out.println("UserServiceImpl.register");
} @Override
public Boolean login(String name, String password) {
System.out.println("UserServiceImpl.login "+name+" "+password );
return true;
}
}

增强类UserPoxyBefore

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class UserPoxyBefore implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("UserPoxyBefore.before"); }
}

接着执行业务代码A

 @Test
public void test2() {
ApplicationContext context=new ClassPathXmlApplicationContext("/ApplicationContext2.XML");
UserServiceImpl userService= (UserServiceImpl) context.getBean("UserServicePiont");
userService.login("SY", "123456");
userService.register(new User());
}
}

就发现额外方法没有执行

输出是这样的

	2021-05-24 20:51:36 DEBUG DefaultListableBeanFactory:225 - Creating shared instance of singleton bean 							'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
UserServiceImpl.login SY 123456
UserServiceImpl.register

并没有输出预期的UserPoxyBefore.before

检查发现不知在UserServiceImpl处添加进入了Advice接口,Advice接口本身没有任何方法,难以发现

去掉即可

结果如下

UserPoxyBefore.before
UserServiceImpl.login SY 123456
UserPoxyBefore.before
UserServiceImpl.register

正确执行

总结:在组装好切点和指定好切面方法之后发现,没有执行,则需要检查接口是否为原始类所implements的接口
也算是一点小坑吧

无法通过getBean()

这个是在总结获取不了增强类时发现的,给自己打个预防针

在获取对象时,由于已经做了组装好切点和指定好切面方法,所以Spring获取的应该是代理对象而非原始对象所以在业务中使用原始对象获取Bean肯定会出问题

具体如下

业务代码B

@Test
public void test2() {
ApplicationContext context=new ClassPathXmlApplicationContext("/ApplicationContext2.XML");
UserServiceImpl userService= (UserServiceImpl) context.getBean("UserServicePiont");
userService.login("SY", "123456");
userService.register(new User());
}

从之前的代码可以知道UserServiceImpl是原始代码

我尝试执行下出如下结果

	java.lang.ClassCastException: com.sun.proxy.$Proxy6 cannot be cast to org.Service.UserServiceImpl

说com.sun.proxy.$Proxy6不能变为org.Service.UserServiceImpl

由此看出spring代理的对象早已不是原来的对象了

在搜索了其他人的分析发现

aop切面插入后该bean被jdk内部自动转为了com.sun.proxy.$Proxy25类型类型已被转变,所以无法通过类UserServiceImpl进行获取

那么如何获取后如何执行该类的代理方法呢?

很简单 使用原始类所implements的接口即可如上面业务代码A那样即可

有人问获取后如何执行该原始类的方法呢?

好像使用反射可以达到目的,在此不再研究,具体生产环境遇到再说,继续学习。

Spring AOP获取不了增强类(额外方法)或无法通过getBean()获取对象的更多相关文章

  1. Spring AOP切面变成——创建增强类

    说明 Spring使用增强类定义横向逻辑,同时Spring只支持方法连接点,增量类还包含在方法的哪一点添加横切代码的方位信息.所以增强既包含横向逻辑,又包含部分连接点的信息. 类型 按着增强在目标类方 ...

  2. Spring学习(七)——增强类

    Spring 切点 什么是切点?切点(Pointcut),每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点,即连接点是程序类中客观存在的事物.但在这为数从多的连接点中,如何定位 ...

  3. (精简)Spring框架的IoC(替代工厂类实现方法)和AOP(定义规则,约定大于配置)

    Spring的核心框架主要包含两个技术,分别用来处理工厂类,以及事务处理和连接管理的. 两大核心概念 1)  IoC:控制反转,在现在的开发中,如果想建立对象并设置属性,是需要先new对象,再通过se ...

  4. Spring AOP中使用args表达式访问目标方法的参数

    Spring AOP 的使用过程理解 首先,aop的使用场景介绍: 1.处理一些通用的非功能性的需求,不影响业务流程,比如说打印日志.性能统计.推送消息等: 2.aop无法拦截static.final ...

  5. 工作随笔——Java调用Groovy类的方法、传递参数和获取返回值

    接触Groovy也快一年了,一直在尝试怎么将Groovy引用到日常工作中来.最近在做一个功能的时候,花了点时间重新看了下Java怎么调用Groovy的方法.传递参数和获取返回值. 示例Groovy代码 ...

  6. vue.js 父组件主动获取子组件的数据和方法、子组件主动获取父组件的数据和方法

    父组件主动获取子组件的数据和方法 1.调用子组件的时候 定义一个ref <headerchild ref="headerChild"></headerchild& ...

  7. SpringMVC + Spring + MyBatis 学习笔记:在类和方法上都使用RequestMapping如何访问

    系统:WIN8.1 数据库:Oracle 11GR2 开发工具:MyEclipse 8.6 框架:Spring3.2.9.SpringMVC3.2.9.MyBatis3.2.8 先看代码: @Requ ...

  8. Spring MVC中如何指定某个类或方法自适配地响应某个HTTP请求?

    方法已经找到,即调用AbstractHandlerMethodAdapter.handle() public final ModelAndView handle(HttpServletRequest  ...

  9. spring aop获取目标对象的方法对象(包括方法上的注解)

    这两天在学习权限控制模块.以前看过传智播客黎活明老师的巴巴运动网视频教程,里面就讲到权限控制的解决方案,当时也只是看看视频,没有动手实践,虽说看过几遍,可是对于系统中的权限控制还是很迷茫,所以借着这次 ...

随机推荐

  1. python中zip函数的使用

    zip(*iterables) zip可以将多个可迭代对象组合成一个迭代器对象,通过迭代取值,可以得到n个长度为m的元组.其中n为长度最短可迭代对象的元素个数,m为可迭代对象的个数.并且每个元组的第i ...

  2. iNeuOS工业互联平台,发布:消息管理、子用户权限管理、元件移动事件、联动控制和油表饼状图,v3.4版本

    目       录 1.      概述... 2 2.      平台演示... 2 3.      消息管理... 2 4.      子用户权限管理... 3 5.      元件移动事件... ...

  3. Androidd Studio 之多行文字跑马灯特效

    •效果展示图 •参考资料 两种方法实现TextView跑马灯效果(字体横向滚动) •出现的问题 新建 Java 文件继承 TextView 时出现问题: •解决方法 不应该继承 $TextView$ ...

  4. Java进阶专题(二十八) Service Mesh初体验

    前言 ​ ⽬前,微服务的架构⽅式在企业中得到了极⼤的发展,主要原因是其解决了传统的单体架构中存在的问题.当单体架构拆分成微服务架构就可以⾼枕⽆忧了吗? 显然不是的.微服务架构体系中同样也存在很多的挑战 ...

  5. SpringCloud+Nacos实现服务配置中心(Hoxton版本)

    关于 Nacos Spring Cloud 的详细文档请参看:Nacos Config和Nacos Discovery. 通过 Nacos Server 和 spring-cloud-starter- ...

  6. elasticsearch之Java调用本地代码

    虽然Java虚拟机为开发人员屏蔽了底层的实现细节,使得开发人员不用考虑底层操作系统的差异性.不过在某些应用程序中,还是免不了要直接与底层操作系统上的原生代码进行交互.今天我们就来看一下Java对本地调 ...

  7. 痞子衡嵌入式:从头开始认识i.MXRT启动头FDCB里的lookupTable

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT启动头FDCB里的lookupTable. 一个MCU内部通常有很多外设模块,这些外设模块是各MCU厂商做差异化产品的本质, ...

  8. 【C/C++】malloc和new的区别

    malloc和new的区别 malloc是C语言的内存申请函数.new是C++语言的运算符.所以在.c文件中无法使用new. malloc申请空间时,传递的是size.new申请空间时,传递的是typ ...

  9. 消息中间件rabbitMQ

    1 为什么使用消息队列啊? 其实就是问问你消息队列都有哪些使用场景,然后你项目里具体是什么场景,说说你在这个场景里用消息队列是什么 面试官问你这个问题,期望的一个回答是说,你们公司有个什么业务场景,这 ...

  10. 《疯狂Kotlin讲义》读书笔记6——函数和Lambda表达式

    函数和Lambda表达式 Kotlin融合了面向过程语言和面向对象语言的特征,相比于Java,它增加了对函数式编程的支持,支持定义函数.调用函数.相比于C语言,Kotlin支持局部函数(Lambda表 ...