在另一个实例变量中使用自动装配参数
Using an autowired parameter in another instance variable
我有一个实现接口的服务。我现在想写一个映射器,基本上就是说,当我传入这个枚举类型时,使用那个服务。这就是我的
@Service
MyService implements Service {}
@Component
@RequiredArgsConstructor
MyMapper implements Mapper<Enum, Service> {
private final MyService myService;
private ImmutableMap<Enum, Service> MAPPER = ImmutableMap.<MyEnum, MyService>builder()
.put(Enum.A, myService)
.build();;
@Override
public Service map(Enum input) {
return MAPPER.get(input);
}
}
不过,这好像不行。我想我不允许使用(自动装配的)实例变量来实例化另一个实例变量。
为了解决这个问题,我现在使用了单例模式。
@Service
MyService implements Service {}
@Component
@RequiredArgsConstructor
MyMapper implements Mapper<Enum, Service> {
private final MyService myService;
private ImmutableMap<Enum, Service> MAPPER = null;
@Override
public Service map(Enum input) {
if(MAPPER == null){
MAPPER = createMapper();
}
return MAPPER.get(input);
}
private ImmutableMap<Enum, Service> createMapper(){
return ImmutableMap.<MyEnum, MyService>builder()
.put(Enum.A, myService)
.build();;
}
}
这似乎可行,但我想知道是否有其他选择可以解决这个问题。
您运行正在考虑最终变量的边缘情况;即使它被标记为最终的,映射的初始化语句 运行s 在实例初始化程序块之前(否则会有用),运行 在对变量进行赋值的构造函数主体之前。
我不确定您为什么要创建一个映射来保存单例值,但您需要在构造函数主体内分配映射。如果出于某种原因你真的想要这个设置,我的建议是这样做:
private final Map<Enum, Service> MAPPER;
public MyMapper(MyService myService) {
MAPPER = Map.of(Enum.A, myService);
}
对于这个问题,服务定位器最适合。
我的枚举:-
public enum MyEnum {
A,
B
}
创建服务并使用名称 "A" 和 "B"(您的枚举名称为字符串):-
@Service("A")
MyService1 implements Service {}
@Service("B")
MyService2 implements Service {}
创建MyMapper界面:-
public interface MyMapper {
Service map(MyEnum myEnum);
}
配置 ServiceLocatorFactoryBean :-
@Bean
public ServiceLocatorFactoryBean serviceLocatorFactoryBean(){
ServiceLocatorFactoryBean bean = new ServiceLocatorFactoryBean();
bean.setServiceLocatorInterface(MyMapper.class);
return bean;
}
开始使用:-
@Autowired
MyMapper mapper;
我有一个实现接口的服务。我现在想写一个映射器,基本上就是说,当我传入这个枚举类型时,使用那个服务。这就是我的
@Service
MyService implements Service {}
@Component
@RequiredArgsConstructor
MyMapper implements Mapper<Enum, Service> {
private final MyService myService;
private ImmutableMap<Enum, Service> MAPPER = ImmutableMap.<MyEnum, MyService>builder()
.put(Enum.A, myService)
.build();;
@Override
public Service map(Enum input) {
return MAPPER.get(input);
}
}
不过,这好像不行。我想我不允许使用(自动装配的)实例变量来实例化另一个实例变量。
为了解决这个问题,我现在使用了单例模式。
@Service
MyService implements Service {}
@Component
@RequiredArgsConstructor
MyMapper implements Mapper<Enum, Service> {
private final MyService myService;
private ImmutableMap<Enum, Service> MAPPER = null;
@Override
public Service map(Enum input) {
if(MAPPER == null){
MAPPER = createMapper();
}
return MAPPER.get(input);
}
private ImmutableMap<Enum, Service> createMapper(){
return ImmutableMap.<MyEnum, MyService>builder()
.put(Enum.A, myService)
.build();;
}
}
这似乎可行,但我想知道是否有其他选择可以解决这个问题。
您运行正在考虑最终变量的边缘情况;即使它被标记为最终的,映射的初始化语句 运行s 在实例初始化程序块之前(否则会有用),运行 在对变量进行赋值的构造函数主体之前。
我不确定您为什么要创建一个映射来保存单例值,但您需要在构造函数主体内分配映射。如果出于某种原因你真的想要这个设置,我的建议是这样做:
private final Map<Enum, Service> MAPPER;
public MyMapper(MyService myService) {
MAPPER = Map.of(Enum.A, myService);
}
对于这个问题,服务定位器最适合。
我的枚举:-
public enum MyEnum {
A,
B
}
创建服务并使用名称 "A" 和 "B"(您的枚举名称为字符串):-
@Service("A")
MyService1 implements Service {}
@Service("B")
MyService2 implements Service {}
创建MyMapper界面:-
public interface MyMapper {
Service map(MyEnum myEnum);
}
配置 ServiceLocatorFactoryBean :-
@Bean
public ServiceLocatorFactoryBean serviceLocatorFactoryBean(){
ServiceLocatorFactoryBean bean = new ServiceLocatorFactoryBean();
bean.setServiceLocatorInterface(MyMapper.class);
return bean;
}
开始使用:-
@Autowired
MyMapper mapper;