13. 인덱싱 서비스 코딩 [광고 시스템의 단계를 구현하여 봄 클라우드 단계]

하나에 우리가 광고 색인 유지 보수를 분석 두 가지이다, 全量索引加载하고 增量索引维护. 광고를 광고 시스템은 가장 중요한 부분을 검색하기 때문에, 우리는 우리의 인덱스 디자인의 아이디어를 이해하기주의해야합니다 우리는 인덱스 유지 관리 기능을 코딩 온.

우리는 인덱스 변경 검색 작업의 모든 추가 사항을 수신하는 인터페이스, 인터페이스가, 패러다임을 정의하는 두 개의 매개 변수, 수신 정의 K색인의 대표 키 값, V반환 값의 대표.

/**
 * IIndexAware for 实现广告索引的增删改查
 *
 * @author <a href="mailto:[email protected]">Isaac.Zhang | 若初</a>
 */
public interface IIndexAware<K, V> {

    /**
     * 通过key 获取索引
     */
    V get(K key);
    /**
     * 添加索引
     * @param key
     * @param value
     */
    void add(K key, V value);
    /**
     * 更新索引
     */
    void update(K key, V value);
    /**
     * 删除索引
     */
    void delete(K key, V value);
}

우리는뿐만 데이터베이스 테이블의 모든 인덱스, 같은 만들 필요가 있음을 알고 있어야 User우리가 데이터를 검색 할 테이블이 실제로 물론, 인덱스를 생성 할 필요가 없습니다 필요하고 테이블의 모든 필드 인덱스를 필요로된다 이 또한 정보 분야, 우리가 작성하려고 같은 결정하기 위해 특정 사업을 기반으로 推广计划인덱스를 증진 프로그램 이름이 필요하지 않을 수 있습니다. 다음으로, 우리는 우리의 첫 번째를 달성 正向索引.

  • 첫째, 엔티티 객체 조작 추진 계획을 작성
/**
 * AdPlanIndexObject for 推广计划索引对象
 * 这个索引对象我们没有添加 推广计划名称
 * @author <a href="mailto:[email protected]">Isaac.Zhang | 若初</a>
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AdPlanIndexObject {

    private Long planId;
    private Long userId;
    private Integer planStatus;
    private Date startDate;
    private Date endDate;

    /**
    * 根据实际字段来更新索引
    */
    public void update(AdPlanIndexObject newObject) {

        if (null != newObject.getPlanId()) {
            this.planId = newObject.getPlanId();
        }
        if (null != newObject.getUserId()) {
            this.userId = newObject.getUserId();
        }
        if (null != newObject.getPlanStatus()) {
            this.planStatus = newObject.getPlanStatus();
        }
        if (null != newObject.getStartDate()) {
            this.startDate = newObject.getStartDate();
        }
        if (null != newObject.getEndDate()) {
            this.endDate = newObject.getEndDate();
        }
    }
}
  • 그런 다음 인덱스 클래스의 실현을 촉진하고 구현하는 계획을 만들 IIndexAware인터페이스를.
/**
 * AdPlanIndexAwareImpl for 推广计划索引实现类
 *
 * @author <a href="mailto:[email protected]">Isaac.Zhang | 若初</a>
 */
@Slf4j
@Component
public class AdPlanIndexAwareImpl implements IIndexAware<Long, AdPlanIndexObject> {

    private static Map<Long, AdPlanIndexObject> planIndexObjectMap;

    /**
     * 因为操作索引的过程中有可能对索引进行更新,为了防止多线程造成的线程不安全问题,我们不能使用hashmap,需要实现ConcurrentHashMap
     */
    static {
        planIndexObjectMap = new ConcurrentHashMap<>();
    }

    @Override
    public AdPlanIndexObject get(Long key) {
        return planIndexObjectMap.get(key);
    }

    @Override
    public void add(Long key, AdPlanIndexObject value) {

        log.info("AdPlanIndexAwareImpl before add::{}", planIndexObjectMap);
        planIndexObjectMap.put(key, value);
        log.info("AdPlanIndexAwareImpl after add::{}", planIndexObjectMap);
    }

    @Override
    public void update(Long key, AdPlanIndexObject value) {

        log.info("AdPlanIndexAwareImpl before update::{}", planIndexObjectMap);
                //查询当前的索引信息,如果不存在,直接新增索引信息
        AdPlanIndexObject oldObj = planIndexObjectMap.get(key);
        if (null == oldObj) {
            planIndexObjectMap.put(key, value);
        } else {
            oldObj.update(value);
        }

        log.info("AdPlanIndexAwareImpl after update::{}", planIndexObjectMap);
    }

    @Override
    public void delete(Long key, AdPlanIndexObject value) {

        log.info("AdPlanIndexAwareImpl before delete::{}", planIndexObjectMap);
        planIndexObjectMap.remove(key);
        log.info("AdPlanIndexAwareImpl after delete::{}", planIndexObjectMap);
    }
}

지금까지 우리는 코드 인덱스 제목 인덱스 작업을 완료하고 추진 계획은 우리가 완료하려면, 위의 예를 참조 할 수 있습니다, 준비 推广单元, 推广创意, 地域, 兴趣, 关键词推广创意和推广单元的关联索引, 또는에서 직접 Github에서 포털 / Gitee 포털 소스 코드를 다운로드 할 수 있습니다.

위의 코드에 따르면 우리가 정의 된 인덱스 작업을 모두 달성 한 것을 알 수 있지만, 현실에서, 우리는 각각의 서비스를 필요로 이러한 서비스를 사용할 필요 @Autowired도 후속 조치를 포함하지 않는, 우리의 인덱스 작업 클래스의 많은, 사출 인덱스의 차원을 추가하기가해야 할 수도 있습니다, 작업 부하는 자격을 갖춘 프로그래머로, 이것은 매우 쌀쌀, 유지 보수가 너무 큰, 불편하고, 아마 이후의 개발자 BS-ING합니다.

후속 것을 방지하기 위해이 꾸짖 될에서는 인덱스 캐시 도구를 준비해야 com.sxzhongf.ad.index.IndexDataTableUtils제 우려를 해결하기위한 인덱스 버퍼 도구를 주입하여이를 달성 할. 이 유틸리티 클래스를 달성하기 위해, 우리는 두 개의 인터페이스를 구현해야 org.springframework.context.ApplicationContextAware하고org.springframework.core.PriorityOrdered

  • org.springframework.context.ApplicationContextAware내부 운영하고 콩 인스턴스 스프링 컨테이너에 통합 된 인터페이스를 구현하여 클래스입니다.
    봄에하는 Aware한, 간단하게 이해 될 수있다 클래스의 끝을 접미사 응용 프로그램이 XXX 싶어 , 예를 들어, ApplicationContextAware당신이 원하는 응용 프로그램을 대신하여 ApplicationContext, BeanFactoryAware응용 프로그램 당신이 원하는 BeanFactory등 ...
  • org.springframework.core.PriorityOrdered어셈블리를로드하는 순서는, 당신이 사용할 수있는 org.springframework.core.Ordered
    우리의 도구 다음 코드를 :
package com.sxzhongf.ad.index;

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

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * IndexDataTableUtils for 所有索引服务需要缓存的Java Bean
 *
 * 使用方式:
 * 获取{@link com.sxzhongf.ad.index.creative.CreativeIndexAwareImpl}索引服务类
 * 如下:
 * {@code
 *   IndexDataTableUtils.of(CreativeIndexAwareImpl.class)
 * }
 * @author <a href="mailto:[email protected]">Isaac.Zhang | 若初</a>
 */
@Component
public class IndexDataTableUtils implements ApplicationContextAware, PriorityOrdered {

    //注入ApplicationContext
    private static ApplicationContext applicationContext;

    /**
     * 定义用于保存所有Index的Map
     * Class标示我们的索引类
     */
    private static final Map<Class, Object> dataTableMap = new ConcurrentHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        IndexDataTableUtils.applicationContext = applicationContext;
    }

    /**
     * 获取索引服务缓存
     */
    public static <T> T of(Class<T> klass) {
        T instance = (T) dataTableMap.get(klass);
        //如果获取到索引bean,直接返回当前bean
        if (null != instance) {
            return instance;
        }
        //首次获取索引bean为空,写入Map
        dataTableMap.put(klass, bean(klass));
        return (T) dataTableMap.get(klass);
    }

    /**
     * 获取Spring 容器中的Bean对象
     */
    private static <T> T bean(String beanName) {
        return (T) applicationContext.getBean(beanName);
    }

    /**
     * 获取Spring 容器中的Bean对象
     */
    private static <T> T bean(Class klass) {
        return (T) applicationContext.getBean(klass);
    }

    @Override
    public int getOrder() {
        return PriorityOrdered.HIGHEST_PRECEDENCE;
    }
}

추천

출처www.cnblogs.com/zhangpan1244/p/11318481.html