【问题标题】:Non transactional methods are also called by proxy, how to avoid that?非事务方法也被代理调用,如何避免呢?
【发布时间】:2015-10-02 00:11:40
【问题描述】:

我是 spring 的新手,我发现了一个有趣的行为,但不知道如何解决它...我有一个类如下:

@组件 公共类 ScheduleService {

/** The Constant log. */
private static final Logger log = LoggerFactory.getLogger(ScheduleService.class);

/** The schedule repository. */
@Autowired
private ScheduleRepository  scheduleRepository;

@Autowired
private PipelineService pipelineService;


private AtomicReference     atomic_scheduler = new AtomicReference();

/**
 * Instantiates a new schedule service.
 */
public ScheduleService() {
}

/**
 * Starts the quarts scheduler instance
 * 
 */
public synchronized void start() {
    ....
}

public Scheduler getScheduler() {
    start();
    return (Scheduler) atomic_scheduler.get();
}

/**
 * Creates the schedule.
 *
 * @param session the session
 * @param schedule the Schedule
 * @return the Schedule
 */
public Schedule createSchedule(Session session, Schedule schedule) throws Exception {

....... }

/**
 * Gets the Schedule.
 *
 * @param session the session
 * @param id the id
 * @return the Schedule
 */
@Transactional(propagation=Propagation.REQUIRES_NEW, isolation=Isolation.READ_COMMITTED)
public Schedule getSchedule(Session session, String id) throws Exception {

..... }

/**
 * Gets the Schedule given the Schedule name.
 *
 * @param session the session
 * @param name the name of the Schedule to return
 * @return the Schedule
 */
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
public Schedule getScheduleByName(Session session, String name) throws Exception {
    ........
}

/**
 */
public Schedule updateSchedule(Session session, Schedule sch) throws Exception {

....... } }

我发现这个类中的所有方法都是由代理调用的,但我不知道为什么...... APO 代理应该只调用“事务”方法吗?我该如何解决这个问题?我希望通过直接调用线程而不通过代理来调用非事务性方法。

感谢大家的建议。

【问题讨论】:

  • 否...为整个对象创建一个代理,而不是该对象的子集(这也不可能)。但只有事务方法会应用建议,其他方法不会。
  • 为什么不希望通过代理调用方法?

标签: java spring spring-boot aspectj spring-aop


【解决方案1】:

基本上不可能只通过代理调用部分方法。

要实现 AOP 行为(在您的情况下为 @Transactional),Spring 必须围绕您的对象构建一个代理,以便它可以拦截带注释的方法的调用。为此,Spring 必须在各处注入代理而不是您的对象。

所以所有其他对象只知道代理。并且只能通过代理进行所有调用。

应该如何让只有事务调用通过代理?这将需要大量的字节码操作来查找对对象上方法的所有调用,而不是根据它们是否是事务性的开始以某种方式重定向它们。还要记住,Spring 不仅支持单例 bean。对于一个类的多个实例,它还必须弄清楚要委托给哪个对象。在各处注入代理比让 Java 从那里正常工作要容易得多。

如果您想了解更多详细信息,您可能需要查看java.lang.reflect.Proxy 并尝试自己构建代理。这将使您了解 Java 动态代理是如何实际工作的。 (如果我没记错的话,Spring 默认也使用这个类作为它的代理。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-16
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 2013-01-04
    • 1970-01-01
    相关资源
    最近更新 更多