Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Can';拦截器中的自动连线字段_Java_Spring_Hibernate - Fatal编程技术网

Java Can';拦截器中的自动连线字段

Java Can';拦截器中的自动连线字段,java,spring,hibernate,Java,Spring,Hibernate,我需要确定在数据库中存储对象时发生的事件。我使用拦截器。 拦截器类如下所示: public class TaskInterceptor extends EmptyInterceptor { @Autowired private TaskNoticeRepository taskNoticeRepository;// my repository class @Transactional @Override public boolean onSave(Ob

我需要确定在数据库中存储对象时发生的事件。我使用拦截器。 拦截器类如下所示:

public class TaskInterceptor extends EmptyInterceptor {

    @Autowired
    private TaskNoticeRepository taskNoticeRepository;// my repository class

    @Transactional
    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        return super.onSave(entity, id, state, propertyNames, types);
    }
}
...<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
    <property name="nestedTransactionAllowed" value="true"/>
</bean>

<bean id="taskInterceptor" class="ru.librait.cs.infrastructure.service.interceptor.crm.TaskInterceptor"/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="ru.librait.cs.model,ru.librait.cs.infrastructure.dto.export"/>
    <property name="entityInterceptor" ref="taskInterceptor" />...
Spring配置文件如下所示:

public class TaskInterceptor extends EmptyInterceptor {

    @Autowired
    private TaskNoticeRepository taskNoticeRepository;// my repository class

    @Transactional
    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        return super.onSave(entity, id, state, propertyNames, types);
    }
}
...<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
    <property name="nestedTransactionAllowed" value="true"/>
</bean>

<bean id="taskInterceptor" class="ru.librait.cs.infrastructure.service.interceptor.crm.TaskInterceptor"/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="ru.librait.cs.model,ru.librait.cs.infrastructure.dto.export"/>
    <property name="entityInterceptor" ref="taskInterceptor" />...

如何修复它?

您创建了一个鸡蛋配置(或循环依赖项):要创建
会话工厂,您需要拦截器。拦截器需要回购协议。回购需要
会话工厂

最简单的解决方案是注入
ApplicationContext
并添加
@PostConstruct
方法:

@Autowired
private ApplicationContext applicationContext;

private TaskNoticeRepository taskNoticeRepository;

@PostConstruct
public void init() {
    taskNoticeRepository = applicationContext.getBean(TaskNoticeRepository.class);
}
这将设置步骤向后移动了一点,通常可以正常工作,但很脆弱

对于类似的事情,我更喜欢使用“init bean”,当应用程序启动时(在
main()
或servlet上下文侦听器中)我从应用程序上下文中获得它,它在创建所有bean之后但在任何“正常”代码有机会运行之前连接这些依赖项

因此会有一个懒惰的initbean,它依赖于拦截器和repo。拦截器将获得一个用于回购的setter。bean将有一个公共的
init()
方法来调用setter


这就避免了各种可能有效或可能无效的“神奇”设置代码。

问题是循环依赖,是糟糕的设计。。但是你可以试试

  <bean id="taskInterceptor" class="ru.librait.cs.infrastructure.service.interceptor.crm.TaskInterceptor">
 <property name="taskNoticeRepository" ref="taskNoticeRepository"/>
   </bean>

并删除@Autowired
或者在TaskInterceptor上添加@Component注释,并从xml中删除bean声明,如果ApplicationContext也返回null,则实现ApplicationContextAware可以解决此问题

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContext implements ApplicationContextAware {

    private static ApplicationContext context;

    public static <T extends Object> T getBean(Class<T> beanClass) {
        return context.getBean(beanClass);
    }

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        SpringContext.context = context;
    }
}

你能发布整个堆栈跟踪吗?你能分享第二种方法的链接吗?不,你必须仔细阅读我的答案,理解基本概念并将其应用于你的情况。