Spring 的 @Lookup 注解使用

最近工作中重构代码,需要将prototype类型的组件注入到singleton类型的组件中,但是只是声明scope是prototype,并使用@autowire注入的话,并不能满足需要。个人理解是项目启动的时候已经组装好了,导致单例bean中的原型bean也是同一个。

1. 介绍

我们来看一下如何通过方法级的@Lookup注解完成依赖注入。

2. 为什么用@Lookup?

一个有@Lookup注解的方法会告诉Spring,当我们调用这个方法时,Spring会返回一个方法返回值类型的实例。
实质上,Spring会父爱我们的注解方法并使用我们方法的返回值和参数作为BeanFactory#getBean方法的入参。
@Lookup注解的使用情景:

1) 向一个单例bean注入一个原型bean(prototype-scoped bean)(类似于Provider)
2) Injecting dependencies procedurally(暂译为程序依赖注入,有不妥请指正)
@Lookup相当于XML元素中的lookup-method

3. 如何使用@Lookup

3.1 向一个单例bean注入原型bean

当我们决定使用一个原型bean时,我们必须面对的问题就是我们的单例bean要如何使用这些原型bean呢?
当然可以使用Provider,但是@Lookup在某些方面更合适一些。
首先,我们先创建一个之后需要注入到单例bean的原型bean。

之后我们使用@Lookup创建一个单例bean:

使用@Lookup,我们能在单例bean中得到一个SchoolNotification实例。

注意,在StudentServices中,我们将getNotification方法设置成了一个空方法(we left the getNotification method as a stub)。
这是因为,spring通过调用beanFactory.getBean(StudentNotification.class)重写了这个方法,所以我们能将它置空。
3.2 部分就是说使用@Lookup注入的话,还可以通过构造器传参,其实就是spring调用beanFactory.getBean(class, name)实现的。

示例

下面看一个例子:




可以看到,使用@lookup时,两次的MyHandlerImpl不是同一个对象,而使用autowired注入的话,则是同一个对象。
需要注意的是,被@lookup注解的方法需要是public的哦!

 

0

发表评论

您的电子邮箱地址不会被公开。