or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdapplication-context.mdbean-definition.mdbean-factory.mdbean-processing.mdbean-providers.mdenvironment-config.mdevents.mdexceptions.mdindex.mdscoping.md

bean-providers.mddocs/

0

# Bean Location and Providers

1

2

Bean providers and locators offer flexible, programmatic access to beans in the Micronaut context. They enable lazy instantiation, optional dependencies, and type-safe collection access to beans.

3

4

## Core Interfaces

5

6

### BeanProvider

7

8

Enhanced provider interface that extends Jakarta Provider with additional capabilities for bean introspection and collection access.

9

10

```java { .api }

11

/**

12

* Enhanced provider interface for accessing beans with additional capabilities

13

* @param <T> The bean type

14

*/

15

public interface BeanProvider<T> extends jakarta.inject.Provider<T> {

16

/**

17

* Check if at least one bean of this type is available

18

* @return true if a bean is present

19

*/

20

boolean isPresent();

21

22

/**

23

* Check if exactly one bean of this type is available

24

* @return true if only one bean matches

25

*/

26

boolean isUnique();

27

28

/**

29

* Get an iterator over all available beans of this type

30

* @return Iterator of bean instances

31

*/

32

Iterator<T> iterator();

33

34

/**

35

* Get a stream of all available beans of this type

36

* @return Stream of bean instances

37

*/

38

Stream<T> stream();

39

40

/**

41

* Get the first available bean instance

42

* @return Bean instance

43

* @throws NoSuchBeanException if no bean is available

44

*/

45

@Override

46

T get();

47

}

48

```

49

50

**Usage Examples:**

51

52

```java

53

import io.micronaut.context.BeanProvider;

54

import jakarta.inject.Inject;

55

import jakarta.inject.Singleton;

56

57

@Singleton

58

public class NotificationService {

59

60

// Lazy provider - bean resolved on first access

61

private final BeanProvider<EmailService> emailProvider;

62

63

@Inject

64

public NotificationService(BeanProvider<EmailService> emailProvider) {

65

this.emailProvider = emailProvider;

66

}

67

68

public void sendNotification(String message) {

69

// Check if email service is available before using it

70

if (emailProvider.isPresent()) {

71

EmailService emailService = emailProvider.get();

72

emailService.send(message);

73

}

74

75

// Process all notification handlers

76

emailProvider.stream().forEach(handler -> handler.send(message));

77

}

78

}

79

80

// Multiple implementations scenario

81

@Singleton

82

public class AggregatorService {

83

84

private final BeanProvider<DataProcessor> processors;

85

86

@Inject

87

public AggregatorService(BeanProvider<DataProcessor> processors) {

88

this.processors = processors;

89

}

90

91

public void processData(Data data) {

92

// Use all available processors

93

processors.iterator().forEachRemaining(processor ->

94

processor.process(data)

95

);

96

}

97

}

98

```

99

100

### BeanLocator

101

102

Core interface for locating beans in the context with various resolution strategies.

103

104

```java { .api }

105

/**

106

* Core interface for bean location and resolution

107

*/

108

public interface BeanLocator {

109

/**

110

* Get a required bean of the given type

111

* @param beanType The bean type

112

* @return Bean instance

113

* @throws NoSuchBeanException if bean not found

114

*/

115

<T> T getBean(Class<T> beanType);

116

117

/**

118

* Get a required bean with qualifier

119

* @param beanType The bean type

120

* @param qualifier The qualifier

121

* @return Bean instance

122

* @throws NoSuchBeanException if bean not found

123

*/

124

<T> T getBean(Class<T> beanType, Qualifier<T> qualifier);

125

126

/**

127

* Find an optional bean of the given type

128

* @param beanType The bean type

129

* @return Optional bean instance

130

*/

131

<T> Optional<T> findBean(Class<T> beanType);

132

133

/**

134

* Find an optional bean with qualifier

135

* @param beanType The bean type

136

* @param qualifier The qualifier

137

* @return Optional bean instance

138

*/

139

<T> Optional<T> findBean(Class<T> beanType, Qualifier<T> qualifier);

140

141

/**

142

* Get all beans of the given type

143

* @param beanType The bean type

144

* @return Collection of bean instances

145

*/

146

<T> Collection<T> getBeansOfType(Class<T> beanType);

147

148

/**

149

* Get all beans of the given type with qualifier

150

* @param beanType The bean type

151

* @param qualifier The qualifier

152

* @return Collection of bean instances

153

*/

154

<T> Collection<T> getBeansOfType(Class<T> beanType, Qualifier<T> qualifier);

155

156

/**

157

* Get bean provider for the given type

158

* @param beanType The bean type

159

* @return BeanProvider instance

160

*/

161

<T> BeanProvider<T> getBeanProvider(Class<T> beanType);

162

163

/**

164

* Get bean provider for the given type with qualifier

165

* @param beanType The bean type

166

* @param qualifier The qualifier

167

* @return BeanProvider instance

168

*/

169

<T> BeanProvider<T> getBeanProvider(Class<T> beanType, Qualifier<T> qualifier);

170

}

171

```

172

173

### BeanDefinitionRegistry

174

175

Registry interface providing metadata and introspection capabilities for bean definitions.

176

177

```java { .api }

178

/**

179

* Registry for bean definition metadata and introspection

180

*/

181

public interface BeanDefinitionRegistry {

182

/**

183

* Check if a bean of the given type exists

184

* @param beanType The bean type

185

* @return true if bean exists

186

*/

187

<T> boolean containsBean(Class<T> beanType);

188

189

/**

190

* Check if a bean exists with qualifier

191

* @param beanType The bean type

192

* @param qualifier The qualifier

193

* @return true if bean exists

194

*/

195

<T> boolean containsBean(Class<T> beanType, Qualifier<T> qualifier);

196

197

/**

198

* Find bean definition for the given type

199

* @param beanType The bean type

200

* @return Optional bean definition

201

*/

202

<T> Optional<BeanDefinition<T>> findBeanDefinition(Class<T> beanType);

203

204

/**

205

* Find bean definition with qualifier

206

* @param beanType The bean type

207

* @param qualifier The qualifier

208

* @return Optional bean definition

209

*/

210

<T> Optional<BeanDefinition<T>> findBeanDefinition(Class<T> beanType, Qualifier<T> qualifier);

211

212

/**

213

* Get all bean definitions for the given type

214

* @param beanType The bean type

215

* @return Collection of bean definitions

216

*/

217

<T> Collection<BeanDefinition<T>> getBeanDefinitions(Class<T> beanType);

218

219

/**

220

* Get single bean definition for the given type

221

* @param beanType The bean type

222

* @return Bean definition

223

* @throws NoSuchBeanException if not found

224

* @throws NonUniqueBeanException if multiple found

225

*/

226

<T> BeanDefinition<T> getBeanDefinition(Class<T> beanType);

227

}

228

```

229

230

## Provider Injection Patterns

231

232

### Optional Dependencies

233

234

```java

235

@Singleton

236

public class OptionalFeatureService {

237

238

private final BeanProvider<CacheService> cacheProvider;

239

private final BeanProvider<MetricsService> metricsProvider;

240

241

@Inject

242

public OptionalFeatureService(

243

BeanProvider<CacheService> cacheProvider,

244

BeanProvider<MetricsService> metricsProvider

245

) {

246

this.cacheProvider = cacheProvider;

247

this.metricsProvider = metricsProvider;

248

}

249

250

public String processRequest(String request) {

251

String result = performCoreLogic(request);

252

253

// Optional caching

254

if (cacheProvider.isPresent()) {

255

cacheProvider.get().cache(request, result);

256

}

257

258

// Optional metrics

259

if (metricsProvider.isPresent()) {

260

metricsProvider.get().recordRequest();

261

}

262

263

return result;

264

}

265

}

266

```

267

268

### Collection-based Processing

269

270

```java

271

@Singleton

272

public class PluginManager {

273

274

private final BeanProvider<Plugin> plugins;

275

276

@Inject

277

public PluginManager(BeanProvider<Plugin> plugins) {

278

this.plugins = plugins;

279

}

280

281

public void initializePlugins() {

282

plugins.stream()

283

.sorted(Comparator.comparing(Plugin::getPriority))

284

.forEach(Plugin::initialize);

285

}

286

287

public void processWithPlugins(Event event) {

288

plugins.iterator().forEachRemaining(plugin ->

289

plugin.process(event)

290

);

291

}

292

}

293

```

294

295

### Lazy Initialization

296

297

```java

298

@Singleton

299

public class ExpensiveResourceManager {

300

301

private final BeanProvider<DatabaseConnection> dbProvider;

302

private final BeanProvider<FileSystem> fsProvider;

303

304

@Inject

305

public ExpensiveResourceManager(

306

BeanProvider<DatabaseConnection> dbProvider,

307

BeanProvider<FileSystem> fsProvider

308

) {

309

this.dbProvider = dbProvider;

310

this.fsProvider = fsProvider;

311

}

312

313

public void performDatabaseOperation() {

314

// Database connection only created when needed

315

DatabaseConnection db = dbProvider.get();

316

db.execute("SELECT * FROM users");

317

}

318

319

public void performFileOperation() {

320

// File system only initialized when needed

321

FileSystem fs = fsProvider.get();

322

fs.readFile("config.properties");

323

}

324

}

325

```

326

327

## Types

328

329

### Provider-related Types

330

331

```java { .api }

332

public interface Qualifier<T> {

333

<BT extends BeanType<T>> Stream<BT> reduce(Class<T> beanType, Stream<BT> candidates);

334

boolean equals(Object o);

335

int hashCode();

336

}

337

338

public interface BeanResolutionContext {

339

BeanContext getContext();

340

BeanDefinition<?> getRootDefinition();

341

Path getPath();

342

BeanResolutionContext copy();

343

}

344

345

public interface BeanCreationContext<T> extends BeanResolutionContext {

346

BeanDefinition<T> definition();

347

CreatedBean<T> create() throws BeanCreationException;

348

}

349

```