多平台统一管理软件接口,如何实现多平台统一管理软件接口
252
2023-06-17
Spring中初始化泛型类的方法实例
首先来看下在 java 中对于泛型类型,比如这样简单的类定义
class Processor
如果直接初始化时要指定具体类型的话,我们可以这么写
Processor
Spring 对基本泛型的初始化
如果我们要用 Spring 容器来初始化这个类,比如给上面那个类加个 @Named 注解
@Named
class Processor
}
这时候我们通过 beanFactory.getBean(Processor.class) 得到的是一个什么样的实例呢?Spring 怎么知道要指定什么具体类型呢?很简单,任何不确定的情况都是 Object。所以通过容器得到的 Processor 实例相当于用下面代码构造出来的
Processor processor = new Processor(); //更准确来讲是 Processor
再进一步,对于有上限约束的泛型定义,Spring 才如何应对呢?像
@Named
class Processor
}
类似的,class Processor
Processor
再复杂一些,泛型的子类型仍然是泛型的情况,如下代码
首先定义了一个泛型接口
public interface Service
String process(T t);
}
然后要求 Spring 容器来初始下面的 NumberService 实例
@Named
public class NumberService
@Override
public Strinhttp://g process(R number) {
return "Process Number: " + number;
}
}
Spring 在初始化 NumberService 实例同样是要取用最顶层可接受类型,通过下面的代码来初始化
NumberService
再终极一些,泛型类型并且类型也是泛型的,Spring 该如何拿捏?
@Named
public class Processor
@Inject
Private Service
}
此时 Spring 该如何确定上面的类型 T 呢?因为有了 Service
Processor
而是 Processor 的具体类型必须通过被注入的 Service
如果 Spring 中有初始化
@Named
public class StringService implements Service
@Override
public String process(String string) {
return "Process String: " + string;
}
}
那么前面的 Processor
Processor
processor.service = new StringService();
如果 Spring 中初始化的 Service
Processor
processor.service = new NumberService
那如果前面的 NumberService 和 StringService 同时在 Spring 容器中注册了呢?Spring 同样要为难了,在没有 @Primary 的情况下无法确定使用哪个实例来注入 Service
2016-12-09 00:56:50.922 WARN 4950 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'processor': Unsatisfied dependency expressed through field 'service'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'cc.unmi.Service>' available: expected single matching bean but found 2: numberService,stringService
2016-12-09 00:56:50.941 ERROR 4950 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field service in cc.unmi.Processor required a single bean, but 2 were found:
- numberService: defined in file [/Users/Yanbin/Workspaces/github/spring-generic-demo/target/classes/cc/unmi/NumberService.class]
- stringService: defined in file [/Users/Yanbin/Workspaces/github/spring-generic-demo/target/classes/cc/unmi/StringService.class]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that shohttp://uld be consumed
这和普通属性的注入时有多个可选实例时是一样的错误。
总结一下
如果 Spring 在初始化泛型类时,未提供任何具体类型则会采用最上限的类型来初始化实例
@Named class Processor
@Named class Processor
如果泛型类型与被注入的属性的具体类型有关联,则由属性类型推断出主类型
@Named class Processor
@Inject Service
}
此时 Spring 容器中存在 class StringService implements Service
当然这个 Processor 类也是可以定义的稍复杂一些,如
@Named class Processor
@Inject Service
}
关于本文的示例代码可参考 https://github.com/yabqiu/spring-generic-demo, 请运行 mvn spring-boot:run 查看输出结果来理解 Spring 怎么去初始化泛型类实例的。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用Spring能带来一定的帮助,如果有疑问大家可以留言交流。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~