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. 全面了解Vue3的 reactive 和相关函数

    Vue3的 reactive 怎么用,原理是什么,官网上和reactive相关的那些函数又都是做什么用处的?这里会一一解答. ES6的Proxy Proxy 是 ES6 提供的一个可以拦截对象基础操作 ...

  2. Android Stuio让我濒临崩溃的bug之cause: unable to find valid certification path to requested target

    •问题描述 像往常一样,打开 $android studio$ 开启愉快的开发之旅: 写着写着,右下角弹出一个对话,说 $android studio$ 有新版本可更新: 有新版本为何不用,果断点击 ...

  3. C语言之通讯录的模拟实现

    C语言之通讯录的模拟实现 在C语言学习结束之际,谨以此篇文章来对C语言的学习告一段落. 纲要: 通讯录的静态版本 通讯录的动态版本 通讯录的带文件版本 因为三种实现方法除了储存形式不同,其他都基本相同 ...

  4. redis常用数据类型对应的数据结构

    redis的数据类型都是通过多种数据结构来实现,主要是出于时间和空间的考虑,当数据量小的时候通过数组下标访问最快,占用内存最小[压缩列表是数组的变种,允许存储的数据大小不同] 因为数组需要占用连续的内 ...

  5. Java代理模式,一次复习完4种动态代理实现方式

    代理模式也是一种非常常见的设计模式.了解Spring框架的都知道,Spring AOP 使用的就是动态代理模式.今天就来系统的重温一遍代理模式. 在现实生活中代理是随处可见的,当事人因某些隐私不方便出 ...

  6. 构建一个Flowable命令行应用

    官网链接 [(https://flowable.com/open-source/docs/bpmn/ch02-GettingStarted/#building-a-command-line-appli ...

  7. 【剑指offer】8:跳台阶

    题目描述: 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). 解题思路: 这种题目多为找规律求通用公式并最终用代码实现. 首先,考 ...

  8. Python多环境管理——pyenv

    1 背景&概述 因某些需求,需要安装TensorFlow,很自然地在终端敲下了以下命令: pip install tensorflow 然后... 好家伙??? 居然没有?? 因为是Pytho ...

  9. manjaro 手动调节屏幕亮度

    1 问题描述 manjaro版本20.0,桌面XFCE,设置之类的地方没有屏幕亮度调节的功能. 2 解决方案 解决方案来自arch wiki. 亮度由ACPI内核模块控制,这个模块的接口在以下位置: ...

  10. python 匿名函数,内置函数

    一 :匿名函数 匿名就是没有名字 def func(x,y,z=1): return x+y+z 匿名 lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使 ...