什么是泛型依赖注入?
- 在java中设计类和方法或者设计接口的时候,如果不确定使用什么样的类型参数,可以使用泛型作为参数,而在子类实现类或复写方法的时候,在指定具体类型的参数.泛型就起到这样一个减少重复代码的作用(:如果没有泛型那得设计多少个重载方法,仅仅只是参数类型不同 ?)
- 那么在Spring中为带有泛型的Bean进配置注入的时候,会根据子类实现时指明的类型来注入对应的泛型类型的变量.(原谅我表述不清楚,可以直接写代码就能懂了.)
示例
- 文字说明总结的不好,难以理解,直接写一遍代码吧
- 定义两个java类对应数据表中的两个数据表,由于只是模拟,就简单写吧
- User
- Role
public class User {
}
public class Role {
}
- 通常情况下都会将实体类的增删改查操作,定义在一个接口中,以作为一个标准,由于每个数据表中的主键类型和具体的实体类类型是不一样的,所以使用泛型表示.
/**
* 定义增删改查的标准
* @param <K> 数据表的主键类型
* @param <V> 数据表的实体类
*/
public interface DAOUtil<K,V> {
public boolean doCreate(V vo);
public boolean doRemove(K id);
public boolean doUpdate(V vo);
public V doSearch(K id);
}
- 而每一个实体类都会有一个自己的DAO操作类,这个操作类必须继承自DAOUtil这个操作标准接口,在实现的时候必须指定表明泛型的类型.
定义UserDAO
@Repository
public class UserDAO implements DAOUtil<Integer,User> {
@Override
public boolean doCreate(User vo) {
return false;
}
@Override
public boolean doRemove(Integer id) {
return false;
}
@Override
public boolean doUpdate(User vo) {
return false;
}
@Override
public User doSearch(Integer id) {
return null;
}
}
- 定义RoleDAO
@Repository
public class RoleDAO implements DAOUtil<Integer,Role> {
@Override
public boolean doCreate(Role vo) {
return false;
}
@Override
public boolean doRemove(Integer id) {
return false;
}
@Override
public boolean doUpdate(Role vo) {
return false;
}
@Override
public Role doSearch(Integer id) {
return null;
}
}
- 通常情况下为了让代码能够更好的重用性,不会直接使用DAO操作类进行增删改查操作,往往会定义一个服务层,而服务层需要一个DAO的操作对象.
- 并且服务层也会定义一个标准的接口,任何服务操作类也需要实现这个接口,为了演示方便,使用普通类描述
package mao.shu.spring.genericity;
import org.springframework.beans.factory.annotation.Autowired;
public class ServiceBase<K,V> {
@Autowired
private DAOUtil<K,V> dao;//Spring会根据子类继承时定义的类型自动注入
public void add(V v){
dao.doCreate(v);
System.out.println("执行"+ dao.getClass() + "add()方法");
}
}
- 编写RoleService类,继承自ServiceBase,使用"@Service"注解标明让Spring管理
@Service
public class RoleService extends ServiceBase<Integer,Role> {
}
- 编写UserService类
@Service
public class UserService extends ServiceBase<Integer,User> {
}
- 配置genericity.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="mao.shu.spring.genericity"/>
</beans>
- 测试使用Spring获取UserService和RoleService类的对象,并调用add()方法,观察他们的父类中的DAOUtil属性是什么类型的
package mao.shu.spring.genericity;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import static org.junit.Assert.*;
public class UserServiceTest {
private ApplicationContext app;
@Before
public void before() {
this.app = new ClassPathXmlApplicationContext("mao/shu/spring/genericity/genericity.xml");
}
@Test
public void test(){
RoleService roleService = this.app.getBean("roleService",RoleService.class);
UserService userService = this.app.getBean("userService",UserService.class);
roleService.add(new Role());
userService.add(new User());
}
}
这其中发生了什么呢?
在ServiceBase这个类之中,定义了一个DAOUtil类的属性,并在定义的时候,依然使用泛型描述DAOUtil的泛型参数,虽然此时IDEA提示找不到匹配的Bean,但不影响程序,
- 并在add()方法中输出这个DAOUtil属性的参数类型
- 但是在写ServiceBase的子类RoleService和UserService的时候,明确指明:"K"和"V"这两个泛型的具体类型
- 因此Spring会自动根据子类所指定的泛型类型注入对应的参数类型的属性,所以在最后使用ad()方法输出不同子类的DAOUtil类型的时候,所出现的是不同的DAOUtil的子类对象