如何使用由ApplicationListener ConfigurableApplicationContext初始化的服务

时间:2018-12-15 16:46:30

标签: java spring mybatis

我使用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 {
}

我初始化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());
    }

但是当我在conroller中使用entityService时,不能使用由ApplicationListener初始化的entityService。 这就是我尝试使用EntityService

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

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

使用Idea调试,我可以找到具有非null映射器的EntityService。 但是在控制器中,三个EntityService映射器都为空。 如何将EntityService与ApplicationListener初始化的映射器一起使用?

1 个答案:

答案 0 :(得分:0)

Spring使用beanPostProcessors链,它可以通过CGLIB或动态代理修改您的初始类。所以this.mapper = SpringContextUtil.getBean(getMapperClass());可能无法按您预期的那样工作