在引导持久性缓存存储工厂类中,spring boot autowired对象被设置为null

时间:2017-12-13 11:14:37

标签: java spring-boot cassandra ignite

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

这是我的示例点燃配置文件:

//The GameObject with the pivot point to move
public GameObject pointToRotate;
//The Pivot point to move the GameObject around
public Transform pivotPoint;

//The angle to Move the pivot point
public Vector3 angle = new Vector3(0f, 180f, 0f);

//The duration for the rotation to occur
public float rotDuration = 5f;

void Start()
{
    StartCoroutine(rotateObject(pointToRotate, pivotPoint.position, angle, rotDuration));
}

这是我的ItemCacheStore类代码:

<?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>

在调用load方法的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; } } 字段为itemRepository。但是,当我在另一个控制器类中自动装配相同的null bean时,它可以正常工作。

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

1 个答案:

答案 0 :(得分:0)

问题是以下配置:

<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会创建{strong>新实例 ItemCacheStore。 Spring不会管理这个新实例,因此所有字段都是null

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

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

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

  1. 使用不同的工厂或编写自己的工厂,使用Spring托管bean而不是创建新的。根据文档,已经有CassandraCacheStoreFactory
  2. 使用this answer中提到的AutowireHelper,或使用Springs SpringBeanAutowiringSupport在非Spring托管bean中注入bean。
  3. 相关:Why is my Spring @Autowired field null?