【问题标题】:spring boot autowired object is getting set to null in ignite persistence cachestore factory classspring boot autowired对象在ignite persistence cachestore工厂类中设置为null
【发布时间】:2017-12-13 11:14:37
【问题描述】:

我使用 Apache Ignite 2.3 和 cassandra 2.1.9 作为我的持久层。 我正在使用 cacheStoreFactory 类来保存和获取数据库中的数据。 我在这个类中自动连接一些依赖项,但它是空的。

这是我的示例 ignite 配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       ">
    <description>Main Spring file for ignite configuration.</description>

    <bean id="cacheIgniteBean" class="org.apache.ignite.IgniteSpringBean">
        <property name="configuration">
            <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
                <property name="dataStorageConfiguration">
                    <bean class="org.apache.ignite.configuration.DataStorageConfiguration">
                        <property name="dataRegionConfigurations">
                            <list>
                                <!--
                                    Defining a data region that will consume up to 2 GB of RAM.
                                -->
                                <bean class="org.apache.ignite.configuration.DataRegionConfiguration">
                                    <!-- Custom region name. -->
                                    <property name="name" value="2GB_Region"/>

                                    <!-- 500 MB initial size (RAM). -->
                                    <property name="initialSize" value="#{500L * 1024 * 1024}"/>

                                    <!-- 2 GB maximum size (RAM). -->
                                    <property name="maxSize" value="#{2L * 1024 * 1024 * 1024}"/>

                                    <!-- Enabling RANDOM_LRU eviction for this region.  -->
                                    <property name="pageEvictionMode" value="RANDOM_LRU"/>
                                </bean>
                            </list>
                        </property>
                    </bean>
                </property>
                <property name="cacheConfiguration">
                    <list>
                        <bean class="org.apache.ignite.configuration.CacheConfiguration">

                            <property name="name" value="item"/>
                            <property name="cacheMode" value="PARTITIONED"/>
                            <property name="atomicityMode" value="ATOMIC"/>
                            <property name="backups" value="0"/>
                            <property name="cacheStoreFactory">
                                <bean class="javax.cache.configuration.FactoryBuilder" factory-method="factoryOf">
                                    <constructor-arg value="com.tgt.gom.cacheserver.store.ItemCacheStore"/>
                                </bean>

                            </property>

                            <property name="readThrough" value="${ignite.config.cache.item.readThrough}"/>
                            <property name="writeThrough" value="${ignite.config.cache.item.writeThrough}"/>
                            <property name="writeBehindEnabled" value="${ignite.config.cache.item.writeBehindEnabled}"/>
                            <property name="writeBehindFlushSize"
                                      value="${ignite.config.cache.item.writeBehindFlushSize}"/>
                            <property name="writeBehindFlushFrequency"
                                      value="${ignite.config.cache.item.writeBehindFlushFrequency}"/>
                            <property name="writeBehindFlushThreadCount"
                                      value="${ignite.config.cache.item.writeBehindFlushThreadCount}"/>
                            <property name="writeBehindBatchSize"
                                      value="${ignite.config.cache.item.writeBehindBatchSize}"/>
                        </bean>

                        <bean class="org.apache.ignite.configuration.CacheConfiguration">

                            <property name="name" value="location"/>
                            <property name="cacheMode" value="PARTITIONED"/>
                            <property name="atomicityMode" value="ATOMIC"/>
                            <property name="backups" value="0"/>
                            <property name="cacheStoreFactory">
                                <bean class="javax.cache.configuration.FactoryBuilder" factory-method="factoryOf">
                                    <constructor-arg value="com.tgt.gom.cacheserver.store.LocationCacheStore"/>
                                </bean>
                            </property>
                            <property name="readThrough" value="${ignite.config.cache.item.readThrough}"/>
                            <property name="writeThrough" value="${ignite.config.cache.item.writeThrough}"/>
                            <property name="writeBehindEnabled" value="${ignite.config.cache.item.writeBehindEnabled}"/>
                            <property name="writeBehindFlushSize"
                                      value="${ignite.config.cache.item.writeBehindFlushSize}"/>
                            <property name="writeBehindFlushFrequency"
                                      value="${ignite.config.cache.item.writeBehindFlushFrequency}"/>
                            <property name="writeBehindFlushThreadCount"
                                      value="${ignite.config.cache.item.writeBehindFlushThreadCount}"/>
                            <property name="writeBehindBatchSize"
                                      value="${ignite.config.cache.item.writeBehindBatchSize}"/>
                        </bean>

                    </list>
                </property>

                <!--<property name="includeEventTypes">
                    <util:constant static-field="org.apache.ignite.events.EventType.EVTS_TASK_EXECUTION"/>
                </property>-->
                <property name="failureDetectionTimeout" value="5000"/>
                <property name="discoverySpi">
                    <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                        <property name="ipFinder">
                            <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                                <!-- <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder"> -->
                                <property name="addresses">
                                    <list>
                                        <value>127.0.0.1:47500..47509</value>
                                    </list>
                                </property>
                            </bean>
                        </property>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
</beans>

这是我的 ItemCacheStore 类代码:

@Slf4j
@Service
public class ItemCacheStore extends CacheStoreAdapter<String, ItemV1DTO> implements Serializable {
    private static final long serialVersionUID = 1L;


    @Autowired
    private ItemRepository itemRepository;

    @Autowired
    private ItemCacheStoreAsync itemCacheStoreAsync;

    private static final String LOG_OP_INFO = "Item_Cache_Store";


    @Override
    public ItemV1DTO load(String item_id) throws CacheLoaderException {
        ItemV1DTO itemV1DTO = null;
        System.out.println("in item cache store ");

        try {
            ItemEntity itemEntity = itemRepository.findOne(item_id);
            if (itemEntity != null) {
                itemV1DTO = mapToItemDTO(itemEntity);
            }
        } catch (Exception e) {
            throw new CacheLoaderException("failed to load item data from cassandra" + e.getMessage());
        }
        return itemV1DTO;
    }
}

在ItemCacheStore类中调用load方法时,itemRepository字段为null。但是,当我在另一个控制器类中自动装配相同的 ItemRepository bean 时,它工作正常。

我注意到的另一件事是,如果我在ItemCacheStore 类中放置一个带有@PostConstruct 注释的方法,那么那时我可以看到ItemRepository 的依赖被注入了,但是当调用加载方法时,它是再次null

【问题讨论】:

    标签: java spring-boot cassandra ignite


    【解决方案1】:

    问题在于以下配置:

    <property name="cacheStoreFactory">
        <bean class="javax.cache.configuration.FactoryBuilder" factory-method="factoryOf">
            <constructor-arg value="com.tgt.gom.cacheserver.store.ItemCacheStore"/>
        </bean>
    </property>
    

    您正在创建一个 FactoryBuilder 类型的 Spring bean,并且您传递了类名 ItemCacheStore。屏幕后面发生的是FactoryBuilder 将创建ItemCacheStore新实例。这个新实例不会由 Spring 管理,因此所有字段都是 null

    所以基本上你会得到两个ItemCacheStore 的实例:

    • 由于@Service 注解,由 Spring 容器创建。所有自动装配的字段都可以使用。
    • 另一个由FactoryBuilder 创建。它不会由 Spring 管理,所有自动装配的字段都是 null

    要解决这个问题,有几种可能性:

    1. 使用不同的工厂或编写自己的工厂,将使用 Spring 托管 bean 而不是创建新的。根据文档,已经有一个CassandraCacheStoreFactory
    2. 使用this answer 中提到的AutowireHelper,或使用Springs SpringBeanAutowiringSupport 在非Spring 托管的bean 中注入bean。

    相关:Why is my Spring @Autowired field null?

    【讨论】:

      猜你喜欢
      • 2014-12-15
      • 1970-01-01
      • 2018-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多