解决实现类添加了@Transactional注解后,无法获取自定义注解的问题

个人博客原文地址:http://www.ltang.me/2016/08/18/get-annotation-aop-proxy/

背景描述

自定义了一个注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface ScheduledTask {
}

在一个实现类上添加此注解:

@ScheduledTask
public class TimerTaskServiceImpl implements TimeTaskService {

在代码中期望通过判断是否包含注解来执行操作:

if(bean.getClass().isAnnotationPresent(ScheduledTask.class)){
...

本来一切运行正常。但是,当我试图在实现类上添加事务注解@Transactional后,这里的判断就一直是false。调试发现,当跑到这一行代码时,bean不是实现类,而是一个Proxy代理类(JdkDynamicAopProxy),所以自定义的注解一直获取不到。搜索之后,才知道这是spring的事务管理对添加了@Transactional注解的类做了其他操作,我们获取到的是一个处理后的代理类。

解决方案

于是试图使用下面的代码获取到实际的类:

Object target = ((SingletonTargetSource)((Advised) processor.getIface()).getTargetSource()).getTarget();

或者简单点:

Class<?> = ((Advised) processor.getIface()).getTargetClass();

然而由于框架里面ClassLoader不一致的问题,导致不能直接转换,所以只能通过反射的方式获取到实际类:

long count = new ArrayList<>(Arrays.asList(processor.getIface().getClass().getInterfaces()))
.stream()
.filter(m -> m.getName().equals("org.springframework.aop.framework.Advised"))
.count();

Class<?> ifaceClass = (Class) (count > 0 ? processor.getIface().getClass().getMethod("getTargetClass").invoke(processor.getIface()) : processor.getIface().getClass());

if(ifaceClass.isAnnotationPresent(ScheduledTask.class)){
...

解决了这个问题。仅作记录。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`@Transactional`是Spring框架中的一个注解,用于标记方法或,以控制数据库操作(如插入、更新、删除)的并发性和事务管理。它提供了对事务行为的灵活配置,主要的属性包括: 1. ** propagation (传播行为)**: 指定当此@Transactional声明的方法被调用时,如果当前没有事务,则是开启一个新的事务,还是加入到现有的事务中。可选值有REQUIRED, SUPPORTS, REQUIRES_NEW, NOT_SUPPORTED, NEVER等。 2. ** isolation (隔离级别)**: 设置事务的隔离级别,防止脏读、不可重复读和幻影读。常见的隔离级别有ISOLATION_DEFAULT(由底层数据库决定)、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ和SERIALIZABLE。 3. ** rollbackFor (触发回滚的异常)**: 定义当抛出指定型的异常时,事务自动回滚。可以是一个或多个异常型,也可以是自定义异常。 4. ** noRollbackFor (不触发回滚的异常)**: 相反,当抛出这些异常时,不会触发回滚,通常用于处理预期的业务异常。 5. ** readOnly (只读事务)**: 如果设置为true,表示该事务不允许修改数据,主要用于读取操作优化。 6. ** timeout (超时时间)**: 设置事务的超时时间,单位通常是秒。 7. ** name (事务名称)**: 可选属性,提供自定义的事务名称。 8. ** rollbackOnCommitFailure (提交失败时回滚)**: 是否在提交事务失败时自动回滚,默认情况下Spring会重试。 9. ** savepointManager (保存点管理器)**: 可选的SavepointManager接口实现,用于高级事务管理。 10. ** readOnlyProperties (只读属性列表)**: 可选,指定哪些属性在只读事务中仍然允许修改。 通过这些属性,你可以根据需要定制事务的行为,确保代码的健壮性和数据一致性。如果你需要更详细的例子或进一步了解如何使用它们,可以告诉我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值