我需要创建一个从通过查询数据库获得的数据生成的不可修改的地图。我如何,或者我可以,或者有没有更好的方法来使用弹簧注释来做到这一点?
我在为我的Regions类创建单例然后尝试在RegionService中使用@Autowire以从 DAO 中获取对象时遇到问题。问题是spring无法实例化RegionService,因为它需要实例化需要从数据库中获取数据的静态单例类Regions,如下构造函数中所示。
请在下面查看我的课程(我已经删除了多个与此问题无关的不需要的方法):
public final class Region {
private static final String DEFAULT_SEPERATOR = "-";
private final Integer key;
private final String description;
public Region(Integer pKey, String pDescription) {
this.key = pKey;
this.description = pDescription;
}
public Integer getKey() {
return this.key;
}
public String getValue() {
return this.description;
}
}
这是我的单身人士:
public final class Regions {
private static Regions regionsInstance = null;
@Autowired
private RegionService regionService;
static Map<Integer, Region> regions;
private Regions() {
final Map<Integer, Region> tempRegions = new HashMap<Integer, Region>();
for (final Region region : this.regionService.retrieveAll()) {
tempRegions.put(region.getKey(), region);
}
regions = Collections.unmodifiableMap(tempRegions);
}
public static synchronized Regions getRegionsInstance() {
if (regionsInstance == null) {
regionsInstance = new Regions();
}
return regionsInstance;
}
public Region getRegion(final Integer pKey) {
return regions.get(pKey);
}
public List<Region> getRegions() {
return (List<Region>) regions.values();
}
}
我的 DAO 和 Service 只是接口,不需要发布这些,这是我的 Impls:
@Service
public class RegionServiceImpl implements RegionService {
@Autowired
private RegionDAO regionDao;
@Override
public List<Region> retrieveAll() {
return this.regionDao.retrieveAll();
}
}
我的 DAOImpl (经过测试和工作,只是发布给你完整的图片):
@Repository
public class RegionDAOImpl implements RegionDAO {
private static final String SQL_RETRIEVE_REGIONS = "some random SQL";
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<Region> retrieveAll() {
try {
return this.jdbcTemplate.query(SQL_RETRIEVE_REGIONS, new ResultSetExtractor<List<Region>>() {
@Override
public List<Region> extractData(ResultSet rs) throws SQLException, DataAccessException {
return RegionDAOImpl.this.mapRegionData(rs);
}
});
} catch (final DataAccessException dae) {
throw new DaoException("Could not retrieve regionList from database. " + dae);
}
}
protected final List<Region> mapRegionData(ResultSet rs) throws SQLException {
final List<Region> regionList = new ArrayList<Region>();
while (rs.next()) {
regionList.add(new Region(rs.getInt("REGION_CD"), rs.getString("REGION_TXT")));
}
return Collections.unmodifiableList(regionList);
}
}
然后我运行我的测试(我拿出了不需要的废话):
@..annotated with things you don't need to know
public class RetrieveRegionsTest {
@Autowired
private Regions r;
@Test
public void getAndLogRegion() {
final List<Region> regionDescriptions = new ArrayList<Region>(this.r.getRegions());
for (final Region region : regionDescriptions) {
LOGGER.info(region.getValue());
}
}
是的,我的配置和类路径设置正确。我可以让它以其他方式工作,而不是通过访问我想要的Regions单例。现在我知道我可以在我的 Regions 单例中取消RegionService上的@Autowired并创建一个新的 RegionService 实例,但这会破坏 springs @Autowired 功能的目的。
有什么想法、想法、评论吗?