Как использовать сервис, созданный ApplicationListener ConfigurableApplicationContext - PullRequest
0 голосов
/ 15 декабря 2018

Я использую springMvc и mybatis. Скопируйте BaseService и BaseServiceImpl из проекта.

public interface BaseService<Record, Example> {
    //init mybatis mapper
    void initMapper();
}

BaseServiceImpl

public abstract class BaseServiceImpl<Mapper, Record, Example> implements BaseService<Record, Example> {

public Mapper mapper;
@Override
public void initMapper() {
    this.mapper = SpringContextUtil.getBean(getMapperClass());
}


public Class<Mapper> getMapperClass() {
    return (Class<Mapper>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}

EntityServiceImpl

@Service
@Transactional
@BaseService
public class EntityServiceImpl extends BaseServiceImpl<EntityMapper, Entity, EntityExample> implements EntityService {
}

I init BaseServiceиспользуйте этот код.

@Component
public class ApplicationContextListener implements ApplicationListener<ContextRefreshedEvent> {

    private static final Logger LOGGER = Logger.getLogger(ApplicationContextListener.class);

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        // root application context
        if(null == contextRefreshedEvent.getApplicationContext().getParent()) {
            LOGGER.debug(">>>>> spring init finished <<<<<");
            //  call BaseService initMapper method
            ConfigurableApplicationContext applicationContext = (ConfigurableApplicationContext)contextRefreshedEvent.getApplicationContext();
            Map<String, Object> baseServices = applicationContext.getBeansWithAnnotation(BaseService.class);
            for(Object service : baseServices.values()) {
                try {
                    Method initMapper = service.getClass().getMethod("initMapper");
                    initMapper.invoke(service);
                } catch (Exception e) {
                    LOGGER.error("init BaseService initMapper failed", e);
                    e.printStackTrace();
                }
            }

          }
    }

}

при запуске проекта был вызван метод entityServiceImpl.initMapper

@Override
    public void initMapper() {
        this.mapper = SpringContextUtil.getBean(getMapperClass());
    }

, но когда я использую entityService в контроллере. Не могу использовать entityService, который имеетбыл инициирован ApplicationListener.Вот как я пытаюсь использовать entityService

@Conroller 
public class LoginController {
@Resource
EntityService EntityService1;
@Autowired
EntityService EntityService2;

EntityService EntityService3 = (EntityService)SpringContextUtil.getBean(EntityService.class);
}

Использовать отладку Idea, я могу найти EntityService с ненулевым сопоставителем.Но в контроллере все три EntityService Mapper является нулевым.Как я могу использовать EntityService с маппером, инициированным ApplicationListener?

1 Ответ

0 голосов
/ 15 декабря 2018

Spring использует цепочку beanPostProcessors и может изменять ваш начальный класс с помощью CGLIB или динамического прокси.Так что this.mapper = SpringContextUtil.getBean (getMapperClass ());может работать не так, как вы ожидаете

...