向容器中注入泛型
泛型依赖注入是spring4.0之后新添的一个功能,那么什么是泛型注入呢?现在不妨我们想象一个很常见的场景就是图书管理系统中的 dao层,service层。
在dao层分别有userdao和bookdao他们都需要链接数据库,而在service层中也同样有两个service 分别是Userservice和Bookservice,很明显在同一个包下的类他们在功能上有很强的相同行,那不妨在新加两个类,分别是BaseService和BaseDao,把他们的功能抽取出来,工程结构如下:
很显然这两个包中的user和book文件都要继承Base文件的,所以我们在两个Base类中加上泛型(相当于形参),现在假设BaseDao中仅仅是一个保存的功能。
BaseDao
public abstract class BaseDao <T>{
public abstract void testSave();
}
因为这是一个抽象类,不能被实例化,因此不需要加入到IOC容器中,以下是他的子类:
BookDao
@Repository
public class BookDao extends BaseDao<Book>{
public void testSave() {
System.out.println("图书正在保存");
}
}
UserDao
@Repository
public class UserDao extends BaseDao <user>{
public void testSave() {
System.out.println("user正在保存");
}
}
同理service包中的三个文件也是一样的,因为把功能进行了抽取,所以只需要在BaseService中注入Dao:
public class BaseService<T> {
@Autowired
BaseDao<T> baseDao;
public void save() {
baseDao.testSave();
}
}
BookService
@Service
public class BookService extends BaseService{
}
@Service
public class UserService extends BaseService<user> {
}
以下是测试结果:
public class IocTest4 {
ApplicationContext ioc = new ClassPathXmlApplicationContext("Application.xml");
@Test
public void test() {
BookService bookService = ioc.getBean(BookService.class);
bookService.save();
UserService userService = (UserService) ioc.getBean("userService");
userService.save();
}
}
好了,现在大家肯定有这样疑问:
- BaseDao类都没有注入到IOC容器中但是为什么可以使用@Autowired注解在BaseService中装配BaseDao,并且userService 和bookService 在getBean的时候是怎么找到各自对应的dao方法
因为BaseService的两个子类注入到了容器中,而子类继承了BaseService就相当与携带了父类中的baseDao属性,他在携带的过程中因为是这个属性使用了泛型,且子类继承BaseService的时候也传入了相应的数据类型,所以相当于分别向BookService和UserService两个子类中注入了BookDao和UserDao,所以在使用getBean()的时候会分别调用两个不同的testSave方法!