Spring @Lookup
创始人
2025-05-30 11:41:47
0

1. Overview

In this quick tutorial, we’ll take a look at Spring's method-level dependency injection support, via the @Lookup annotation.


2. Why @Lookup?

A method annotated with @Lookup tells Spring to return an instance of the method's return type when we invoke it.

Essentially, Spring will override our annotated method and use our method’s return type and parameters as arguments to BeanFactory#getBean.

@Lookup is useful for:

  • Injecting a prototype-scoped bean into a singleton bean (similar to Provider)
  • Injecting dependencies procedurally

Note also that @Lookup is the Java equivalent of the XML element lookup-method.


3. Using @Lookup

3.1. Injecting prototype-scoped Bean Into a Singleton Bean

If we happen to decide to have a prototype Spring bean, then we are almost immediately faced with the problem of how will our singleton Spring beans access these prototype Spring beans?

Now, Provider is certainly one way, though @Lookup is more versatile in some respects.

First, let’s create a prototype bean that we will later inject into a singleton bean:

@Component
@Scope("prototype")
public class SchoolNotification {// ... prototype-scoped state
}

And if we create a singleton bean that uses @Lookup:

@Component
public class StudentServices {// ... member variables, etc.@Lookuppublic SchoolNotification getNotification() {return null;}// ... getters and setters
}

Using @Lookup, we can get an instance of SchoolNotification through our singleton bean:

@Test
public void whenLookupMethodCalled_thenNewInstanceReturned() {// ... initialize contextStudentServices first = this.context.getBean(StudentServices.class);StudentServices second = this.context.getBean(StudentServices.class);assertEquals(first, second); assertNotEquals(first.getNotification(), second.getNotification()); 
}

Note that in StudentServices, we left the getNotification method as a stub.

This is because Spring overrides the method with a call to beanFactory.getBean(StudentNotification.class), so we can leave it empty.


3.2. Injecting Dependencies Procedurally

Still more powerful, though, is that @Lookup allows us to inject a dependency procedurally, something that we cannot do with Provider.

Let’s enhance StudentNotification with some state:

@Component
@Scope("prototype")
public class SchoolNotification {@Autowired Grader grader;private String name;private Collection marks;public SchoolNotification(String name) {// ... set fields}// ... getters and setterspublic String addMark(Integer mark) {this.marks.add(mark);return this.grader.grade(this.marks);}
}

Now, it is dependent on some Spring context and also additional context that we will provide procedurally.

We can then add a method to StudentServices that takes student data and persists it:

public abstract class StudentServices {private Map notes = new HashMap<>();@Lookupprotected abstract SchoolNotification getNotification(String name);public String appendMark(String name, Integer mark) {SchoolNotification notification = notes.computeIfAbsent(name, exists -> getNotification(name)));return notification.addMark(mark);}
}

At runtime, Spring will implement the method in the same way, with a couple of additional tricks.

First, note that it can call a complex constructor as well as inject other Spring beans, allowing us to treat SchoolNotification a bit more like a Spring-aware method.

It does this by implementing getSchoolNotification with a call to beanFactory.getBean(SchoolNotification.class, name).

Second, we can sometimes make the @Lookup-annotated method abstract, like the above example.

Using abstract is a bit nicer-looking than a stub, but we can only use it when we don't component-scan or @Bean-manage the surrounding bean:

@Test
public void whenAbstractGetterMethodInjects_thenNewInstanceReturned() {// ... initialize contextStudentServices services = context.getBean(StudentServices.class);    assertEquals("PASS", services.appendMark("Alex", 89));assertEquals("FAIL", services.appendMark("Bethany", 78));assertEquals("PASS", services.appendMark("Claire", 96));
}

With this setup, we can add Spring dependencies as well as method dependencies to SchoolNotification.


4. Limitations

Despite @Lookup‘s versatility, there are a few notable limitations:

  • @Lookup-annotated methods, like getNotification, must be concrete when the surrounding class, like Student, is component-scanned. This is because component scanning skips abstract beans.
  • @Lookup-annotated methods won’t work at all when the surrounding class is @Bean-managed.

In those circumstances, if we need to inject a prototype bean into a singleton, we can look to Provider as an alternative.


参考:
@Lookup Annotation in Spring

相关内容

热门资讯

Opentss代码测试 这是个多方门限签名库,使用rust实现。 代码包含两个功能,秘密共享密钥...
Python爬虫:从js逆向了... 最近在网上看到一个可以下载音乐的网站,觉得它那个下载比较繁琐,于是就想用Python爬虫来得到音乐的...
泰国罗勇府素帕他果园:泰东果园... 在泰国东部,有一片令人心驰神往的水果圣地——罗勇府的Suphattraland(素帕他果园)。踏入这...
别纠结!山药鸡蛋到底能不能搭?... 在厨房烹饪的世界里,食材的搭配总是充满了奇妙的化学反应。有人说“食物相生相克”,也有人坚信“万物皆可...
3 步完成!QQ 弹弹的水果布... 炎炎夏日,来一份清凉 Q 弹的水果布丁再合适不过!无需复杂工具和步骤,仅需 3 步,就能用家常食材做...
零食大明星休闲零食店 人气爆棚... 零食大明星休闲零食店 人气爆棚的秘密 走进“零食大明星”,首先映入眼帘的是琳琅满目的零食货架。从香脆...
原创 家... #图文打卡计划#端午节快到了,家家户户都飘着粽叶香。不过光吃粽子怎么够?尤其是家里有小朋友的,总得整...
糖醋白萝卜腌制新法!爽口又开胃... 糖醋白萝卜,一道经典的中国家常小菜,以其爽脆的口感和酸甜的味道赢得了广大食客的喜爱。今天,我将为大家...
像我这样做道菠萝咕咾肉,酸酸甜... 谁说下厨不能像变魔术?今天这道菠萝咕咾肉,保证让你收获全家"哇塞"的惊叹声!金黄酥脆的肉块裹着晶莹剔...
冬瓜干制作方法:享受阳光的味道 冬瓜,这一家常的食材,不仅可以做成各种美味的菜肴,还可以通过晒干的方式,将其独特的味道和口感保存下来...
一个粽子热量是多少?甜粽咸粽如... 当端午节遇上儿童节 粽香与欢乐撞个满怀! 大朋友想解馋又怕胖? 小朋友吃粽子要注意什么? 别急! 这...
好吃的8道家常菜,做法简单,俗... 谁说家常菜不能惊艳味蕾?今天给大家分享8道超级下饭的家常菜,每一道都是米饭杀手,做法简单到厨房小白也...
Kafka可视化工具-Offs... 目录 一、概述 二、环境信息 三、安装和使用 3.1 下载Offset Explorer 和安装 3...
鹤峰:游客手机不慎落水 安全员... 云上恩施报道(鹤峰通联记者 向申荣 通讯员 常蕾 张丽)5月29日,在鹤峰县屏山大峡谷景区,一名游客...
从凯里出发到北海的自驾游全攻略 自驾游,一直以来都是许多旅行者心中的梦想。在这条从凯里到北海的旅途中,你将会体验到不同的风景、文化与...
从青海湖到敦煌怎么走 嘿小伙伴们,今天我来给大家分享一下从青海湖到敦煌的超棒旅行路线,相信我,这绝对是一场难忘的旅程!我刚...
kivy 高级的组建 简介 Bubble 气泡 可以指定和箭头的方向以及显示图像 或者在Bubble 中添加其他的小部件    ...
风力发电系统的随机调度研究(m... 👨‍🎓个人主页:研学社的博客 💥&#...
端午去哪儿?古蔺这些景区活动管... 编辑丨融小妹 来源丨古蔺旅游生活通 端午 出游 指 南 端午假期来啦! 你的“避暑山...
上海年轻人跟团乐|西北8日游拔... 西北8日游拔草记|1.5K起全含食宿行,年轻人也能轻松玩转大西北! 🌈 初识阿洁:一位让人安心的向导...