Java 如何注册实现同一接口的类的对象
我有这样一个映射JavaBean的接口Java 如何注册实现同一接口的类的对象,java,interface,Java,Interface,我有这样一个映射JavaBean的接口 public interface Mapper <K,V> { K map(V v); V mapReverse(K k); } 公共接口映射器{ K图(V); V图反向(K); } 实现示例 public class CarMapper implements Mapper<Car, CarDTO> { public Car map(CarDTO dto) { //implementat
public interface Mapper <K,V> {
K map(V v);
V mapReverse(K k);
}
公共接口映射器{
K图(V);
V图反向(K);
}
实现示例
public class CarMapper implements Mapper<Car, CarDTO> {
public Car map(CarDTO dto) {
//implementation
};
public CarDTO mapReverse(Car car) {
//implementation
};
}
公共类CarMapper实现映射器{
公共汽车地图(CarDTO dto){
//实施
};
公共卡至地图倒车(汽车){
//实施
};
}
现在我想为所有这些实现提供一个公共访问点,这样用户就不必记住所有实现的名称
例如:-
public class MapperFacade {
public static<K,V> K map(V v, Class<K> k, Class<V> v) {
//1) get the appropriate mapper implementation (throw an exception if no such implementation is found)
//2) map the object
//3) return the object
}
}
公共类MapperFacade{
公共静态K图(V,K类,V类){
//1) 获取适当的映射器实现(如果未找到此类实现,则引发异常)
//2) 映射对象
//3) 返回对象
}
}
现在我有两个问题:-
1) 如何在运行时获得适当的映射器实现,并知道调用哪个方法(map或mapReverse)
2) 如果映射器实现分布在不同的java项目中,我如何创建一个框架,其中每个映射器实现可以在一个中心位置注册自己,然后可以通过一个公共点进行访问,如上文所述我没有测试过这一点,但类似的情况如何。使用类作为键在地图中注册映射器。更完整的实现将使用可分配检查,而不仅仅是精确的类匹配。如果要映射的值是基类的子类
public class MapperFacade<K,V> implements Mapper<K,V> {
private Map<Class<K>,Mapper<K,V>> keyMappers = new HashMap<Class<K>,Mapper<K,V>>();
private Map<Class<V>,Mapper<K,V>> valueMappers = new HashMap<Class<V>,Mapper<K,V>>();
public void addMapper(Mapper<K,V> mapper, Class<K> keyClass, Class<V> valueClass) {
keyMappers.put(keyClass, mapper);
valueMappers.put(valueClass, mapper);
}
public K map(V value) {
Mapper<K,V> mapper = valueMappers.get(value.getClass());
return mapper.map(value);
}
public V mapReverse(K key) {
Mapper<K,V> mapper = keyMappers.get(key.getClass());
return mapper.mapReverse(key);
}
}
公共类MapperFacade实现映射器{
私有映射keyMappers=newhashmap();
私有映射valueMappers=newhashmap();
public void addMapper(映射器映射器、类keyClass、类valueClass){
keyMappers.put(keyClass,mapper);
valueMappers.put(valueClass,Mappers);
}
公共K图(V值){
Mapper Mapper=valueMappers.get(value.getClass());
返回mapper.map(值);
}
公共V映射反向(K键){
Mapper Mapper=keyMappers.get(key.getClass());
返回mapper.mapReverse(键);
}
}
或者通过提供类使映射方法“不那么神奇”,就像在代码中一样(MapperFacade不再实现映射器)
public K映射(V值,Class值Class){
Mapper Mapper=valueMappers.get(valueClass);
返回mapper.map(值);
}
公共V映射反向(K键,Class键Class){
Mapper Mapper=keyMappers.get(keyClass);
返回mapper.mapReverse(键);
}
这假设每个类有一个映射器。如果同一个类可能有多个映射器,则可能需要使用单个HashMap,但密钥需要使用一个bean,该bean由类
和类
或两个映射组成
private Map<Class<K>,Map<Class<V>,Mapper<K,V>>> keyMappers = ...
private Map<Class<V>,Map<Class<K>,Mapper<K,V>>> valueMappers = ...
私有映射键映射器=。。。
私有映射值映射程序=。。。
您正在重新实施番石榴。用那个
1) 如何在运行时和运行时获得适当的映射器实现
知道要调用哪个方法(map或mapReverse)
要在运行时探索元级别信息,可以尝试以下操作
它允许您在运行时“查询”类定义元数据:
Reflections reflections = new Reflections("my.project");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
Reflections=newreflections(“my.project”);
设置所以我最近自己用spring解决了这个问题。
这是解决办法
首先,将映射器接口重构为:-
public abstract class Mapper <Entity, DTO> {
private static final MapperFactory mapperFactory = MapperFactory.getInstance();
public Mapper() {
mapperFactory.registerMapper(getEntityClass(), getDTOClass(),this);
}
public abstract Entity map(DTO object);
public abstract DTO mapReverse(Entity object);
public abstract Class<Entity> getEntityClass();
public abstract Class<DTO> getDTOClass();
}
public class MapperFactory {
private Map<String, Mapper> mappers = new ConcurrentHashMap<>(); //MapperFactory is a singleton class, ConcurrentHashMap ensures thread safety.
private static final MapperFactory INSTANCE = new MapperFactory();
public static MapperFactory() {
return MapperFactory.INSTANCE;
}
public <Entity, DTO> void registerMapper(Class<Entity> entityClass, Class<DTO> dtoClass, Mapper<Entity, DTO> mapper) {
mappers.put(dtoClass.getCanonicalName(), mapper);
mappers.put(entityClass.getCanonicalName(), mapper);
}
public <T> Mapper getMapper(Class<T> sourceClass) {
mappers.get(sourceClass.getCanonicalName());
}
}
公共抽象类映射器{
私有静态最终MapperFactory MapperFactory=MapperFactory.getInstance();
公共映射器(){
registerMapper(getEntityClass(),getDTOClass(),this);
}
公共抽象实体映射(DTO对象);
公共抽象数据到mapReverse(实体对象);
公共抽象类getEntityClass();
公共抽象类getDTOClass();
}
公共类MapperFactory{
private Map mappers=new ConcurrentHashMap();//MapperFactory是一个单例类,ConcurrentHashMap确保线程安全。
私有静态最终MapperFactory实例=新建MapperFactory();
公共静态MapperFactory(){
返回MapperFactory.INSTANCE;
}
公共无效注册表映射器(类entityClass、类dtoClass、映射器映射器){
put(dtoClass.getCanonicalName(),mapper);
put(entityClass.getCanonicalName(),mapper);
}
公共映射器getMapper(类sourceClass){
get(sourceClass.getCanonicalName());
}
}
对于用于访问所有映射器的公共接口,请使用此类:-
public class MapperFacade {
private MapperFactory mapperFactory = MapperFactory.getInstance();
public <Entity, DTO> DTO entityToDTO(Entity entity, Class<DTO> dtoClass) {
Mapper<Entity, DTO> mapper = mapperFactory.getMapper(entity.getClass());
return mapper.mapReverse(entity);
}
public <Entity, DTO> Entity dtoToEntity(DTO dto, Class<Entity> entityClass) {
Mapper<Entity, DTO> mapper = mapperFactory.getMapper(dto.getClass());
return mapper.map(dto);
}
}
公共类MapperFacade{
私有MapperFactory MapperFactory=MapperFactory.getInstance();
公共DTO entityToDTO(实体,类dtoClass){
Mapper Mapper=mapperFactory.getMapper(entity.getClass());
返回mapper.mapReverse(实体);
}
公共实体dtoToEntity(DTO DTO,类entityClass){
Mapper Mapper=mapperFactory.getMapper(dto.getClass());
返回mapper.map(dto);
}
}
现在,为了自动注册任何映射器,我们可以使用spring的@Component注释。例如:-
@Component
public class CarMapper <Car, CarDTO> {
public Car map(CarDTO carDTO) {
//impl
}
public CarDTO mapReverse(Car car) {
//impl
}
public Class<Car> getEntityClass() {
return Car.getClass();
}
public Class<CarDTO> getDtoClass() {
return CarDTO.getClass();
}
}
@组件
公共级卡马佩尔{
公共汽车地图(CarDTO CarDTO){
//恳求
}
公共卡至地图倒车(汽车){
//恳求
}
公共类getEntityClass(){
return Car.getClass();
}
公共类getDtoClass(){
返回CarDTO.getClass();
}
}
因此,现在您不必关心映射器类是什么,也不需要自己在一些初始化代码中注册它们。我认为没有办法做到这一点。。但是您可以使用生成器类。。使用键和值类作为参数来构建..是否在某处保留一个映射
?详细说明并称之为MapperRegistry
?很多ORM都有这样一个门面:Mapper=ORM.createDto(Car.class)
您似乎在寻找服务提供者接口。可能包括一个命令
@Component
public class CarMapper <Car, CarDTO> {
public Car map(CarDTO carDTO) {
//impl
}
public CarDTO mapReverse(Car car) {
//impl
}
public Class<Car> getEntityClass() {
return Car.getClass();
}
public Class<CarDTO> getDtoClass() {
return CarDTO.getClass();
}
}