`
jinnianshilongnian
  • 浏览: 21514971 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2420711
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:3010449
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5640704
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:260256
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1598034
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:250392
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5860757
Group-logo
跟我学Nginx+Lua开...
浏览量:702961
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:785824
社区版块
存档分类
最新评论

Spring4新特性——泛型限定式依赖注入

阅读更多

Spring4新特性——泛型限定式依赖注入

Spring4新特性——核心容器的其他改进

Spring4新特性——Web开发的增强

Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC 

Spring4新特性——Groovy Bean定义DSL

Spring4新特性——更好的Java泛型操作API 

Spring4新特性——JSR310日期API的支持

Spring4新特性——注解、脚本、任务、MVC等其他特性改进 

 

Spring 4.0已经发布RELEASE版本,不仅支持Java8,而且向下兼容到JavaSE6/JavaEE6,并移出了相关废弃类,新添加如Java8的支持、Groovy式Bean定义DSL、对核心容器进行增强、对Web框架的增强、Websocket模块的实现、测试的增强等。其中两个我一直想要的增强就是:支持泛型依赖注入、对cglib类代理不再要求必须有空参构造器了。具体更新请参考:

http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/htmlsingle/#new-in-4.0

 

1、相关代码:

1.1、实体

public class User implements Serializable {
    private Long id;
    private String name;
}

public class Organization implements Serializable {
    private Long id;
    private String name;
}

 1.2、Repository

public abstract class BaseRepository<M extends Serializable> {
    public void save(M m) {
        System.out.println("=====repository save:" + m);
    }
}

@Repository
public class UserRepository extends BaseRepository<User> {
}

@Repository
public class OrganizationRepository extends BaseRepository<Organization> {
}

 对于Repository,我们一般是这样实现的:首先写一个模板父类,把通用的crud等代码放在BaseRepository;然后子类继承后,只需要添加额外的实现。

 

1.3、Service

1.3.1、以前Service写法

public abstract class BaseService<M extends Serializable> {
    private BaseRepository<M> repository;
    public void setRepository(BaseRepository<M> repository) {
        this.repository = repository;
    }
    public void save(M m) {
        repository.save(m);
    }
}
@Service
public class UserService extends BaseService<User> {
    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        setRepository(userRepository);
    }
}

@Service
public class OrganizationService extends BaseService<Organization> {
    @Autowired
    public void setOrganizationRepository(OrganizationRepository organizationRepository) {
        setRepository(organizationRepository);
    }
}

 

可以看到,以前必须再写一个setter方法,然后指定注入的具体类型,然后进行注入;

 

1.3.2、泛型Service的写法

public abstract class BaseService<M extends Serializable> {
    @Autowired
    protected BaseRepository<M> repository;

    public void save(M m) {
        repository.save(m);
    }
}

@Service
public class UserService extends BaseService<User> {
}

@Service
public class OrganizationService extends BaseService<Organization> {
}

 

 大家可以看到,现在的写法非常简洁。支持泛型式依赖注入。

 

这个也是我之前非常想要的一个功能,这样对于那些基本的CRUD式代码,可以简化更多的代码。

 

 

如果大家用过Spring data jpa的话,以后注入的话也可以使用泛型限定式依赖注入 :

@Autowired
private Repository<User> userRepository;

 

 对于泛型依赖注入,最好使用setter注入,这样万一子类想变,比较容易切换。比如https://github.com/zhangkaitao/es,如果有多个实现时,子类可以使用@Qualifier指定使用哪一个。

 

21
3
分享到:
评论
41 楼 error_lei 2017-03-28  
Java泛型编译之后类型信息不就被擦除了吗,
spring是怎么做到注入的。
40 楼 a785975139 2016-10-03  
zbz 写道
一直用的是@Resource来代替@Autowire,因为觉得这更加符合JavaEE的规范,没想到在这里就出问题了


多谢提醒,我把@Resource改为@Autowire就成功了
39 楼 w156445045 2016-05-21  
jinnianshilongnian 写道
awake0474 写道
我用的spring3.2.1 。 好像也支持泛型限定式依赖注入

你是怎么用的?



GenericsUtils

以前写的一个工具类

通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends
* GenricManager<Book>
就可以实现这个问题了。
38 楼 jxlanxin 2016-01-28  
suntopo 写道
“tao哥”呀,我用泛型注入+spring-data-jpa就不成功,不知道原因在哪里。
完全是照着您的es写的
首先写一个泛型的BaseRepository<T,ID>
然后在写一个UserService extends BaseService<User,Long>
在里面用
@Autowired
private BaseRepository<User,Long> baseRepository;获取

我这样写就有问题,这个bean就获取不来,我该如何操作呢,您那里可以是为什么呢
和factory-class有关吗


同样无法成功,请问使用了“@NoRepositoryBean”对BaseRepository进行注解,怎么能够还把baseRepository用来@Autowired?
37 楼 yuanman2002 2015-10-27  
学习了,都是牛人啊 
36 楼 龙鸣 2015-08-26  
有个疑问:子类的自定义方法怎么调用呢,一般的dao层子类都会有自己的自定义操作方法的吧,即使你真的注入了,代码也过不了编译器吧。

BaseDao<T extends Model>{}

UserDao<User> extends BaseDao{
   List<User> select();
}

UserService<User>{
   
    BaseDao<User> dao;
    void count()
    {
       dao.select();
    }
}
35 楼 suntopo 2015-03-19  
“tao哥”呀,我用泛型注入+spring-data-jpa就不成功,不知道原因在哪里。
完全是照着您的es写的
首先写一个泛型的BaseRepository<T,ID>
然后在写一个UserService extends BaseService<User,Long>
在里面用
@Autowired
private BaseRepository<User,Long> baseRepository;获取

我这样写就有问题,这个bean就获取不来,我该如何操作呢,您那里可以是为什么呢
和factory-class有关吗
34 楼 zbz 2014-09-23  
一直用的是@Resource来代替@Autowire,因为觉得这更加符合JavaEE的规范,没想到在这里就出问题了
33 楼 lancijk 2014-08-20  
大牛,得顶一顶.. 膜拜学习中...
32 楼 jinnianshilongnian 2014-08-18  
awake0474 写道
我用的spring3.2.1 。 好像也支持泛型限定式依赖注入

你是怎么用的?
31 楼 awake0474 2014-08-18  
我用的spring3.2.1 。 好像也支持泛型限定式依赖注入
30 楼 userapplewings 2014-03-12  
jinnianshilongnian 写道
userapplewings 写道
学习了,我想请问这种反省依赖注入能够写成spring的xml形式呢?在xml中如何实现呢?是将BaseRepository,注入到BaseService中的BaseRepository么?

可以在xml中配置的;但是必须使用注解注入依赖


果然是必须用注解注入,我想问的就是注入部分是不是还能写成xml,昨天想了半天,感觉xml貌似做不了了
29 楼 jinnianshilongnian 2014-03-12  
userapplewings 写道
学习了,我想请问这种反省依赖注入能够写成spring的xml形式呢?在xml中如何实现呢?是将BaseRepository,注入到BaseService中的BaseRepository么?

可以在xml中配置的;但是必须使用注解注入依赖
28 楼 userapplewings 2014-03-12  
学习了,我想请问这种反省依赖注入能够写成spring的xml形式呢?在xml中如何实现呢?是将BaseRepository,注入到BaseService中的BaseRepository么?
27 楼 jinnianshilongnian 2014-01-02  
hantsy 写道
我所期待的是 Spring 能够 produces 和 Inject Generic type bean。。。

这个已经在 Seam 2 及 CDI 中提供了很长时间,Spring4 依然不支持。 Spring 落伍太多了。

现在这种 Generic Type Injection 只是代替 Qualifer 的一种表示方式。

http://my.oschina.net/hantsy/blog/186939


看了下javaee7的CDI规范,确实很强大;
26 楼 jinnianshilongnian 2013-12-31  
jinnianshilongnian 写道
jinnianshilongnian 写道
hantsy 写道
我所期待的是 Spring 能够 produces 和 Inject Generic type bean。。。

这个已经在 Seam 2 及 CDI 中提供了很长时间,Spring4 依然不支持。 Spring 落伍太多了。

现在这种 Generic Type Injection 只是代替 Qualifer 的一种表示方式。

http://my.oschina.net/hantsy/blog/186939



因为spring对集合等作了特殊处理 可以参考http://jinnianshilongnian.iteye.com/blog/1989379

另外我简单的改造了下spring即可支持你说的功能,可以提交下spring看看接受不
https://github.com/zhangkaitao/spring4-showcase/tree/master/spring4-others/src/test/java/com/sishuok/spring4/genericinject

改造的bean工厂如下
https://github.com/zhangkaitao/spring4-showcase/blob/master/spring4-others/src/test/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

目前对xml List定义 也支持的

注:XML方式的话,注入时必须必须指定名字(因为xml中配置的集合没有泛型信息,除非只有一个集合 Bean)   除非bean definition使用ResolvableType 而不是class存储;
25 楼 jinnianshilongnian 2013-12-31  
jinnianshilongnian 写道
hantsy 写道
我所期待的是 Spring 能够 produces 和 Inject Generic type bean。。。

这个已经在 Seam 2 及 CDI 中提供了很长时间,Spring4 依然不支持。 Spring 落伍太多了。

现在这种 Generic Type Injection 只是代替 Qualifer 的一种表示方式。

http://my.oschina.net/hantsy/blog/186939



因为spring对集合等作了特殊处理 可以参考http://jinnianshilongnian.iteye.com/blog/1989379

另外我简单的改造了下spring即可支持你说的功能,可以提交下spring看看接受不
https://github.com/zhangkaitao/spring4-showcase/tree/master/spring4-others/src/test/java/com/sishuok/spring4/genericinject

改造的bean工厂如下
https://github.com/zhangkaitao/spring4-showcase/blob/master/spring4-others/src/test/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

目前对xml List定义 也支持的
24 楼 jinnianshilongnian 2013-12-31  
hantsy 写道
我所期待的是 Spring 能够 produces 和 Inject Generic type bean。。。

这个已经在 Seam 2 及 CDI 中提供了很长时间,Spring4 依然不支持。 Spring 落伍太多了。

现在这种 Generic Type Injection 只是代替 Qualifer 的一种表示方式。

http://my.oschina.net/hantsy/blog/186939



因为spring对集合等作了特殊处理 可以参考http://jinnianshilongnian.iteye.com/blog/1989379

另外我简单的改造了下spring即可支持你说的功能,可以提交下spring看看接受不
https://github.com/zhangkaitao/spring4-showcase/tree/master/spring4-others/src/test/java/com/sishuok/spring4/genericinject
23 楼 hantsy 2013-12-30  
我所期待的是 Spring 能够 produces 和 Inject Generic type bean。。。

这个已经在 Seam 2 及 CDI 中提供了很长时间,Spring4 依然不支持。 Spring 落伍太多了。

现在这种 Generic Type Injection 只是代替 Qualifer 的一种表示方式。

http://my.oschina.net/hantsy/blog/186939

22 楼 jinnianshilongnian 2013-12-19  
manong_java 写道
我貌似找到原因了有两个同类型的Dao:UserDao和UserDao1
且所有Service 继承BaseService<T> ,去掉BaseService的继承则可以正常运行。
这样一来就说明BaseService中的BaseDao<T>不会根据具体的service类型来注入。

public abstract class BaseService<T extends Serializable> {

	@Autowired
	private BaseDao<T> baseDao;
	
	public void save(T t)
	{
		baseDao.save(t);
	}
}

@Service
public class UserService extends BaseService<User> {

	@Autowired
	@Qualifier("UserDao1")
	private BaseDao<User> dao;
	
	@Override
	public void save(User t) {
		System.out.println("重写save user方法:"+t.getName());
		dao.save(t);
	}
}


	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserService userservice=ctx.getBean(UserService.class);
		User user=new User();
		user.setName("张三");
		user.setId(1000);
		userservice.save(user);
	}


jinnianshilongnian 写道
manong_java 写道
jinnianshilongnian 写道
manong_java 写道
他这个泛型支持 能根据user对象 自动注入UserRepository 对象吗?????
可以的啊 比如 Repository<User> 即可注入


我定义了两个Dao:UserDao、UserDao1
我在service实现类中指定使用UserDao1 但没起作用,程序启动抛异常 这是什么原因呢?

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.hulibo.spring.dao.impl.BaseDao] is defined: expected single matching bean but found 2: UserDao,UserDao1


@Service
public class UserService extends BaseService<User> {

	@Autowired
	@Qualifier("UserDao1")
	private BaseDao<User> dao;
	
	@Override
	public void save(User t) {
		System.out.println("重写save user方法:"+t.getName());
		dao.save(t);
	}

}


@Repository("UserDao")
public class UserDao extends BaseDao<User> {

	@Override
	public void save(User t) {
		System.out.println("userDao save :"+t.getName());
	}

	
}



@Repository("UserDao1")
public class UserDao1 extends BaseDao<User> {

	@Override
	public void save(User t) {
		System.out.println("userDao1 save>>>>:"+t.getName());
	}
}




很明显   BaseDao<User>  有两个实现,不过你指定了@Qualifier("UserDao1") 不应该有问题的啊



public abstract class BaseService<T extends Serializable> { 
 
    @Autowired 
    private BaseDao<T> baseDao; 

在那篇文章中 对于这种情况推荐使用setter注入

相关推荐

    C 设计新思维——泛型编程与设计范式之应用 PDF.rar

    C 设计新思维——泛型编程与设计范式之应用 PDF,候捷译序。㆒般人对C templates 的粗略印象,大约停留在「容器(containers)」的制作上。稍有研究由会发现,templates衍生出来的C Generic Programming(泛型编程)技术...

    SpringIOC_泛型依赖注入.zip

    在Spring IOC容器中,我们可以通过泛型依赖注入来指定我们需要注入的对象类型,而无需显式地指定具体类的全限定名。这种方式提高了代码的可读性和可维护性。 1. **泛型接口与实现**:首先,我们可以定义一个泛型...

    SSH笔记-泛型依赖注入

    在Spring 4版本中,泛型依赖注入是一项重要的特性,它极大地提高了代码的灵活性和可维护性。本笔记将深入探讨SSH中的Spring框架如何实现泛型依赖注入。 首先,我们来理解泛型的基本概念。泛型是Java SE 5引入的一种...

    spring4.0 Generic Qualifier(泛型限定).docx

    在Spring 4.0中,一个重要的改进是引入了对泛型依赖注入的支持,这使得开发者可以更加精确地控制依赖关系,从而提高了代码的可读性和类型安全性。在描述的示例中,我们看到`BaseDao`是一个泛型抽象类,它有一个泛...

    net基础——泛型PPT教案学习.pptx

    net基础——泛型PPT教案学习.pptx

    博客《夯实JAVA基本之一——泛型详解(1)》对应源码

    泛型是Java编程语言中的一个重要特性,它在2004年随着JDK 1.5的发布而引入。这个特性极大地增强了Java类、接口和集合的安全性和效率,避免了类型转换的繁琐与潜在错误。在《夯实JAVA基本之一——泛型详解(1)》的博客...

    博客《夯实JAVA基本之一——泛型详解(2)》对应源码

    总的来说,《夯实JAVA基本之一——泛型详解(2)》这篇博客深入剖析了Java泛型的高级特性,帮助开发者更好地理解如何在实际项目中运用泛型,提高代码质量和可维护性。通过学习这些知识点,开发者可以编写出更加高效且...

    Generic_3(泛型限定(下限)-泛型限定(上限的体现)-泛型限定(下限的体现)-泛型限定(通配符的体现)-集合查阅的技巧)

    泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是...

    C#重要知识之——泛型列表List例子

    在C#编程中,泛型列表`List&lt;T&gt;`是一个非常重要的数据结构,它为我们提供了动态数组的功能,并且具有类型安全的特性。这篇文章将深入探讨`List&lt;T&gt;`的使用,包括其基本操作、性能特点以及一些高级用法。 一、基础概念...

    Spring4新特性(6)更好的Java泛型操作APIJa

    在Spring4框架中,开发者们迎来了一项重要的更新——更优的Java泛型操作API。这一新特性极大地提升了代码的可读性和可维护性,同时也为开发者提供了更强大的工具来处理泛型类型。本文将深入探讨Spring4在这个领域所...

    Generic_2(泛型类-泛型方法-泛型接口-泛型限定(上限)

    泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是...

    c#2_0的新特性泛型

    C# 2.0 是微软.NET框架中C#语言的一个重要版本,它引入了许多新特性,其中最具革命性的是泛型。泛型为C#程序员提供了编写高效、类型安全且可重用代码的能力,极大地提高了代码的灵活性和性能。下面我们将深入探讨C# ...

    .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

    最近有个需求就是一个抽象仓储层接口方法需要SqlServer以及Oracle两种实现方式,为了灵活我在依赖注入的时候把这两种实现都给注入进了依赖注入容器中,但是在服务调用的时候总是获取到最后注入的那个方法的实现,这...

    细细品味C#(泛型专题)

    - **类型通配符**:Java 引入了 `extends` 和 `super` 关键字来支持上下界限定,这使得 Java 的泛型比 C# 更具灵活性。 - **示例解析** 以下示例展示了如何在 Java 中使用类型通配符解决泛型问题: ```java ...

    Java反射、泛型和注解实战之Spring核心注入IOC的实现

    通过这个实战项目,你可以深入理解Java反射、泛型和注解的用法,并且了解到如何利用它们构建一个基本的依赖注入系统,这将有助于你更好地理解和使用Spring框架。同时,这样的实践也有助于提升你的编程技能,使你能够...

    Java8新特性之泛型的目标类型推断_动力节点Java学院

    Java8新特性之泛型的目标类型推断_动力节点Java学院,动力节点口口相传的Java黄埔军校

    Spring 中优雅的获取泛型信息的方法

    Spring 中优雅的获取泛型信息的方法 在 Spring 框架中,获取泛型信息是非常重要的,在实际开发中经常会遇到这种情况。今天,我们来讨论如何在 Spring 中优雅地获取泛型信息。 第一种方法:通过反射获取泛型信息 ...

    Spring3.0新特性

    - **利用 Java 5 特性**:为了更好地利用 Java 5 的新特性,如泛型、变长参数列表等,Spring 3.0 对其核心代码库进行了全面的修订和优化。 - **一致性的使用**:在 Spring 中,现在可以一致性地使用泛型集合和映射...

    jdk1.5新特性,泛型,for:each

    4. **擦除**:Java的泛型在编译后会被擦除,实际运行的字节码不包含泛型信息,但编译时的类型检查仍然有效。 **foreach循环(增强for循环)** 增强for循环,也称为foreach循环,是JDK 1.5中引入的简化迭代集合和数...

Global site tag (gtag.js) - Google Analytics