or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advice-interceptors.mdaspectj-integration.mdauto-proxy.mdcore-abstractions.mdindex.mdpointcuts.mdproxy-creation.mdtarget-sources.md

auto-proxy.mddocs/

0

# Auto-Proxy Creation

1

2

Automatic proxy creation through BeanPostProcessor implementations that analyze beans for advisor applicability and create proxies transparently during the Spring container initialization process. This system enables declarative AOP configuration where proxies are created automatically based on pointcut matching rather than explicit proxy factory configuration.

3

4

## Capabilities

5

6

### Base Auto-Proxy Creator

7

8

Abstract base class providing common functionality for automatic proxy creation during bean post-processing.

9

10

```java { .api }

11

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport

12

implements BeanPostProcessor, BeanFactoryAware {

13

14

/**

15

* Set whether or not the proxy should be frozen, preventing advice

16

* from being added to it once it is created.

17

* <p>Overridden from the superclass to prevent the proxy configuration

18

* from being frozen before the proxy is created.

19

*/

20

@Override

21

public void setFrozen(boolean frozen);

22

23

/**

24

* Set the ordering which will apply to this class's implementation

25

* of Ordered, used when applying multiple BeanPostProcessors.

26

* <p>The default value is {@code Ordered.LOWEST_PRECEDENCE}, meaning non-ordered.

27

* @param order the ordering value

28

*/

29

public void setOrder(int order);

30

31

/**

32

* Return the order value of this object, with a higher value meaning greater

33

* precedence. Normally starting with 0, with {@code Integer.MAX_VALUE}

34

* indicating the greatest precedence (corresponding to the lowest priority).

35

*/

36

@Override

37

public int getOrder();

38

39

/**

40

* Set whether to apply advisors only to beans in this container,

41

* or to beans in the entire BeanFactory hierarchy.

42

* <p>Default is "false": apply advisors to beans in the entire BeanFactory

43

* hierarchy, i.e. including ancestor contexts (as far as they are visible

44

* from the ApplicationContext that this post-processor is defined in).

45

* <p>Switch this flag to "true" in order to apply advisors only to beans

46

* in the local ApplicationContext, ignoring beans in ancestor contexts.

47

* This can be useful if ancestor contexts are read-only, and if you want

48

* to avoid applying advisors to beans defined in read-only contexts.

49

* @param applyCommonInterceptorsFirst whether to apply advisors only locally

50

*/

51

public void setApplyCommonInterceptorsFirst(boolean applyCommonInterceptorsFirst);

52

53

/**

54

* Set custom {@code TargetSourceCreators} to apply to this configuration.

55

* If the list is empty, no custom TargetSource will be applied.

56

* <p>Note that TargetSourceCreators will only be applied if this post-processor

57

* actually creates a proxy for the specific bean. If there are competing

58

* post-processors or if the bean is not eligible for proxying for other reasons,

59

* no custom TargetSource will be applied.

60

* <p>TargetSourceCreators can only be invoked if this post-processor comes first

61

* in the list of BeanPostProcessors; otherwise, the TargetSource will not be

62

* in effect. Custom target sources are disabled by default.

63

* @param targetSourceCreators list of TargetSourceCreator

64

* implementations to apply in the given order

65

*/

66

public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators);

67

68

/**

69

* Set the common interceptors. These must be bean names in the current factory.

70

* They can be of any advice or advisor type Spring supports.

71

* <p>If this property isn't set, there will be zero common interceptors.

72

* This is perfectly valid, if "specific" interceptors such as matching

73

* Advisors are all we want.

74

* @param interceptorNames the list of interceptor names

75

*/

76

public void setInterceptorNames(String... interceptorNames);

77

78

/**

79

* Set the BeanFactory to use. This will be used to retrieve the named

80

* interceptors set in this class.

81

*/

82

@Override

83

public void setBeanFactory(BeanFactory beanFactory);

84

85

/**

86

* Return the owning BeanFactory.

87

* May be {@code null}, as this post-processor doesn't need to belong to a bean factory.

88

*/

89

protected BeanFactory getBeanFactory();

90

91

/**

92

* Create a proxy with the configured interceptors if the bean is

93

* identified as one to proxy by the subclass.

94

* @see #getAdvicesAndAdvisorsForBean

95

*/

96

@Override

97

public Object postProcessBeforeInitialization(Object bean, String beanName);

98

99

/**

100

* Create a proxy with the configured interceptors if the bean is

101

* identified as one to proxy by the subclass.

102

* @see #getAdvicesAndAdvisorsForBean

103

*/

104

@Override

105

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

106

107

/**

108

* Return an array of additional interceptors (or advisors) for the

109

* given bean. Is called if the bean is eligible for proxying.

110

* <p>The returned advisors will be applied to the bean in addition to

111

* any advisors corresponding to common interceptors for the proxy.

112

* Advisors are invoked in the order specified.

113

* <p>The default implementation returns the given advisors as-is.

114

* @param advisors the advisors obtained so far for the particular bean

115

* @param beanName the name of the bean

116

* @param targetClass the class of the bean to be advised

117

* @return the additional advisors for the particular bean;

118

* or the given advisors as-is.

119

* The return value will be added to the advisors list.

120

* Null means no additional advisor.

121

* @throws BeansException in case of errors

122

*/

123

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource customTargetSource) throws BeansException;

124

125

/**

126

* Subclasses should override this to return {@code true} if the

127

* given bean should not be considered for auto-proxying.

128

* <p>Sometimes we need to be able to avoid this happening, e.g. if it will lead to

129

* a circular reference or if the existing target instance needs to be preserved.

130

* This implementation returns {@code false} unless the bean name indicates an

131

* "original instance" according to {@code AutoProxyUtils.isOriginalInstance}.

132

* @param beanClass the class of the bean

133

* @param beanName the name of the bean

134

* @return whether to skip the given bean

135

*/

136

protected boolean shouldSkip(Class<?> beanClass, String beanName);

137

138

/**

139

* Create a target source for bean instances. Uses any TargetSourceCreators if set.

140

* Returns {@code null} if no custom TargetSource should be used.

141

* <p>This implementation uses the "customTargetSourceCreators" property.

142

* Subclasses can override this method to use a different mechanism.

143

* @param beanClass the class of the bean to create a TargetSource for

144

* @param beanName the name of the bean

145

* @return a TargetSource for this bean

146

* @see #setCustomTargetSourceCreators

147

*/

148

protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName);

149

150

/**

151

* Create an AOP proxy for the given bean.

152

* @param beanClass the class of the bean

153

* @param beanName the name of the bean

154

* @param specificInterceptors the set of interceptors that is

155

* specific to this bean (may be empty, but not null)

156

* @param targetSource the TargetSource for the proxy,

157

* already pre-configured to access the bean

158

* @return the AOP proxy for the bean

159

* @see #buildAdvisors

160

*/

161

protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource);

162

163

/**

164

* Determine the advisors for the given bean, including the specific interceptors

165

* as well as the common interceptor, all adapted to the Advisor interface.

166

* @param beanName the name of the bean

167

* @param specificInterceptors the set of interceptors that is

168

* specific to this bean (may be empty, but not null)

169

* @return the list of Advisors for the given bean

170

*/

171

protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors);

172

}

173

```

174

175

### Advisor-Based Auto-Proxy Creators

176

177

Auto-proxy creators that work with Advisor beans in the application context.

178

179

```java { .api }

180

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {

181

/**

182

* Set whether to use the bean name of the advisor bean as the advisor's name,

183

* instead of the default advisor name (which is the simple class name).

184

* <p>Default is "false".

185

* @param useAdvisorBeanNameAsAdvisorName whether to use the bean name as advisor name

186

*/

187

public void setUseAdvisorBeanNameAsAdvisorName(boolean useAdvisorBeanNameAsAdvisorName);

188

189

/**

190

* Return whether to use the bean name of the advisor bean as advisor name.

191

*/

192

public boolean isUseAdvisorBeanNameAsAdvisorName();

193

194

@Override

195

public void setBeanFactory(BeanFactory beanFactory);

196

197

/**

198

* Find all candidate Advisors to use in auto-proxying.

199

* @return the List of candidate Advisors

200

*/

201

protected List<Advisor> findCandidateAdvisors();

202

203

/**

204

* Search the given candidate Advisors to find all Advisors that

205

* can apply to the specified bean.

206

* @param candidateAdvisors the candidate Advisors

207

* @param beanClass the target's bean class

208

* @param beanName the target's bean name

209

* @return the List of applicable Advisors

210

* @see ProxyCreationContext#getCurrentProxiedBeanName()

211

*/

212

protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName);

213

214

/**

215

* Return whether the Advisor bean with the given name is eligible

216

* for proxying in the first place.

217

* @param beanName the name of the Advisor bean

218

* @return whether the bean is eligible

219

*/

220

protected boolean isEligibleAdvisorBean(String beanName);

221

222

/**

223

* Sort advisors based on ordering. Subclasses may choose to override this

224

* method to customize the sorting algorithm.

225

* @param advisors the source List of Advisors

226

* @return the sorted List of Advisors

227

* @see org.springframework.core.Ordered

228

* @see org.springframework.core.annotation.Order

229

* @see org.springframework.core.annotation.AnnotationAwareOrderComparator

230

*/

231

protected List<Advisor> sortAdvisors(List<Advisor> advisors);

232

233

/**

234

* Extension point that allows for providing a custom instance of the

235

* AutoProxyUtils that is used by auto-proxy creators.

236

* <p>The default implementation returns {@code DefaultAutoProxyUtils}.

237

* @return the AutoProxyUtils instance to use

238

* @since 4.2.3

239

*/

240

protected AutoProxyUtils getAutoProxyUtils();

241

}

242

243

public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

244

/**

245

* A marker prefix indicating that the bean name following the prefix is an advisor

246

* that should be included in the proxying process.

247

*/

248

public static final String ADVISOR_BEAN_NAME_PREFIX = "org.springframework.aop.Advisor.";

249

250

/**

251

* Set the prefix that advisor bean names must have.

252

* <p>The default value is {@link #ADVISOR_BEAN_NAME_PREFIX}.

253

* @param advisorBeanNamePrefix the required prefix for advisor bean names

254

*/

255

public void setAdvisorBeanNamePrefix(String advisorBeanNamePrefix);

256

257

/**

258

* Return the prefix that advisor bean names must have.

259

*/

260

public String getAdvisorBeanNamePrefix();

261

}

262

263

public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

264

@Override

265

protected boolean isEligibleAdvisorBean(String beanName);

266

}

267

```

268

269

### Bean Name-Based Auto-Proxy Creator

270

271

Auto-proxy creator that selects beans for proxying based on their bean names.

272

273

```java { .api }

274

public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {

275

/**

276

* Set the names of the beans that should automatically get wrapped with proxies.

277

* A name can specify a prefix to match by ending with "*", e.g. "myBean,tx*"

278

* will match the bean named "myBean" and all beans whose name start with "tx".

279

* <p><b>NOTE:</b> In case of a FactoryBean, only the objects created by the

280

* FactoryBean will get proxied. This default behavior applies as of Spring 2.0.

281

* If you intend to proxy a FactoryBean itself, specify the bean name of the

282

* FactoryBean including the factory-bean prefix "&": e.g. "&myFactoryBean".

283

* @param beanNames the list of bean names

284

*/

285

public void setBeanNames(String... beanNames);

286

287

/**

288

* Set the common interceptors. These must be bean names in the current factory.

289

* They can be of any advice or advisor type Spring supports.

290

* <p>If this property isn't set, there will be zero common interceptors.

291

* This is perfectly valid, if "specific" interceptors such as matching

292

* Advisors are all we want.

293

* @param interceptorNames the list of interceptor names

294

*/

295

public void setInterceptorNames(String... interceptorNames);

296

297

/**

298

* Identify as a bean to proxy if the bean name is in the configured list of names.

299

*/

300

@Override

301

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource customTargetSource);

302

303

/**

304

* Check whether the given bean name is in the configured list of bean names.

305

* @param beanName the bean name to check

306

* @return whether the given bean name is in the configured list of bean names

307

*/

308

protected boolean isMatch(String beanName);

309

}

310

```

311

312

### AspectJ-Aware Auto-Proxy Creator

313

314

Auto-proxy creator that integrates with AspectJ for advanced pointcut expressions and aspect processing.

315

316

```java { .api }

317

public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

318

@Override

319

protected List<Advisor> sortAdvisors(List<Advisor> advisors);

320

321

/**

322

* Add an AspectJPrecedenceComparator decorator to the List returned by

323

* the superclass, so that AspectJ advisors are sorted according to AspectJ rules.

324

* @param advisors the source List of Advisors

325

* @return the sorted List of Advisors

326

* @see org.springframework.aop.aspectj.annotation.AspectJPrecedenceComparator

327

*/

328

@Override

329

protected List<Advisor> sortAdvisors(List<Advisor> advisors);

330

}

331

332

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {

333

/**

334

* Set the list of aspect types for which to create Spring AOP Advisors.

335

* <p>Note: This is supported but not usually necessary. By default, Spring

336

* will automatically detect any @AspectJ classes in the application context.

337

* @param aspectClassNames the list of aspect class names

338

*/

339

public void setIncludePatterns(List<String> includePatterns);

340

341

/**

342

* Set the BeanNameAware bean names for this post-processor.

343

* <p>Note: This is supported but not usually necessary. By default, Spring

344

* will automatically detect any @AspectJ classes in the application context.

345

* @param aspectNames the list of aspect names

346

*/

347

public void setAspectNames(List<String> aspectNames);

348

349

/**

350

* Find all candidate Advisors to use in auto-proxying.

351

* @return the List of candidate Advisors

352

*/

353

@Override

354

protected List<Advisor> findCandidateAdvisors();

355

356

/**

357

* Build AspectJ advisors for all AspectJ aspects in the bean factory.

358

* @see #buildAspectJAdvisors()

359

*/

360

protected List<Advisor> buildAspectJAdvisors();

361

362

@Override

363

protected boolean shouldSkip(Class<?> beanClass, String beanName);

364

365

/**

366

* Check whether the given aspect bean is eligible for auto-proxying.

367

* <p>If no &lt;aop:include&gt; elements were used then "includePatterns" will be

368

* {@code null} and all beans are included. If "includePatterns" is non-null,

369

* then one of the patterns must match.

370

* @param beanName the name of the aspect bean

371

* @return whether the bean is eligible

372

*/

373

protected boolean isEligibleAspectBean(String beanName);

374

}

375

```

376

377

### Support Classes

378

379

Helper classes for auto-proxy creation functionality.

380

381

```java { .api }

382

public class BeanFactoryAdvisorRetrievalHelper {

383

/**

384

* Create a new BeanFactoryAdvisorRetrievalHelper for the given BeanFactory.

385

* @param beanFactory the ListableBeanFactory to scan

386

*/

387

public BeanFactoryAdvisorRetrievalHelper(ListableBeanFactory beanFactory);

388

389

/**

390

* Find all eligible Advisor beans in the current bean factory,

391

* ignoring FactoryBeans and excluding beans that are currently in creation.

392

* @return the list of {@link org.springframework.aop.Advisor} beans

393

* @see #isEligibleBean

394

*/

395

public List<Advisor> findAdvisorBeans();

396

397

/**

398

* Determine whether the aspect bean with the given name is eligible.

399

* <p>The default implementation always returns {@code true}.

400

* @param beanName the name of the aspect bean

401

* @param beanDefinition the corresponding bean definition

402

* @return whether the bean is eligible

403

*/

404

protected boolean isEligibleBean(String beanName, BeanDefinition beanDefinition);

405

}

406

407

public interface TargetSourceCreator {

408

/**

409

* Create a special TargetSource for the given bean, if any.

410

* @param beanClass the class of the bean to create a TargetSource for

411

* @param beanName the name of the bean

412

* @return a special TargetSource or {@code null} if this TargetSourceCreator isn't

413

* interested in the particular bean

414

*/

415

TargetSource getTargetSource(Class<?> beanClass, String beanName);

416

}

417

```

418

419

## Usage Examples

420

421

### Configuring Default Advisor Auto-Proxy Creator

422

423

```java

424

@Configuration

425

@EnableAspectJAutoProxy

426

public class AopConfig {

427

428

// Define advisor beans - they will be automatically applied

429

@Bean

430

public Advisor transactionAdvisor() {

431

AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();

432

pointcut.setExpression("@annotation(org.springframework.transaction.annotation.Transactional)");

433

return new DefaultPointcutAdvisor(pointcut, new TransactionInterceptor());

434

}

435

436

@Bean

437

public Advisor securityAdvisor() {

438

NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();

439

pointcut.setMappedNames("secure*", "admin*");

440

return new DefaultPointcutAdvisor(pointcut, new SecurityInterceptor());

441

}

442

}

443

```

444

445

### Custom Auto-Proxy Creator

446

447

```java

448

@Component

449

public class CustomAutoProxyCreator extends AbstractAutoProxyCreator {

450

451

@Override

452

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource customTargetSource) {

453

// Custom logic to determine which beans should be proxied

454

if (beanClass.isAnnotationPresent(MyCustomAnnotation.class)) {

455

return new Object[] {

456

new LoggingInterceptor(),

457

new PerformanceInterceptor()

458

};

459

}

460

return DO_NOT_PROXY;

461

}

462

463

@Override

464

protected boolean shouldSkip(Class<?> beanClass, String beanName) {

465

// Skip internal Spring beans and configuration classes

466

return super.shouldSkip(beanClass, beanName) ||

467

beanClass.isAnnotationPresent(Configuration.class);

468

}

469

}

470

```

471

472

### Bean Name Auto-Proxy Creator Configuration

473

474

```java

475

@Configuration

476

public class BeanNameAutoProxyConfig {

477

478

@Bean

479

public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {

480

BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();

481

creator.setBeanNames("*Service", "*Repository", "userManager");

482

creator.setInterceptorNames("loggingInterceptor", "transactionInterceptor");

483

return creator;

484

}

485

486

@Bean

487

public MethodInterceptor loggingInterceptor() {

488

return invocation -> {

489

System.out.println("Calling: " + invocation.getMethod().getName());

490

Object result = invocation.proceed();

491

System.out.println("Finished: " + invocation.getMethod().getName());

492

return result;

493

};

494

}

495

496

@Bean

497

public MethodInterceptor transactionInterceptor() {

498

return invocation -> {

499

System.out.println("Starting transaction");

500

try {

501

Object result = invocation.proceed();

502

System.out.println("Committing transaction");

503

return result;

504

} catch (Exception e) {

505

System.out.println("Rolling back transaction");

506

throw e;

507

}

508

};

509

}

510

}

511

```

512

513

### Advanced AspectJ Auto-Proxy Configuration

514

515

```java

516

@Configuration

517

@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)

518

public class AdvancedAopConfig {

519

520

@Bean

521

public AnnotationAwareAspectJAutoProxyCreator autoProxyCreator() {

522

AnnotationAwareAspectJAutoProxyCreator creator = new AnnotationAwareAspectJAutoProxyCreator();

523

creator.setProxyTargetClass(true);

524

creator.setExposeProxy(true);

525

creator.setOrder(Ordered.HIGHEST_PRECEDENCE);

526

527

// Only process beans matching these patterns

528

creator.setIncludePatterns(Arrays.asList(".*Service.*", ".*Controller.*"));

529

530

return creator;

531

}

532

533

@Aspect

534

@Component

535

public class PerformanceAspect {

536

537

@Around("@annotation(org.springframework.cache.annotation.Cacheable)")

538

public Object measureCacheablePerformance(ProceedingJoinPoint joinPoint) throws Throwable {

539

long start = System.currentTimeMillis();

540

Object result = joinPoint.proceed();

541

long executionTime = System.currentTimeMillis() - start;

542

System.out.println("Cacheable method " + joinPoint.getSignature() +

543

" executed in " + executionTime + "ms");

544

return result;

545

}

546

}

547

}

548

```

549

550

### Infrastructure-Only Auto-Proxy Creator

551

552

```java

553

@Configuration

554

public class InfrastructureAopConfig {

555

556

@Bean

557

public InfrastructureAdvisorAutoProxyCreator infrastructureAutoProxyCreator() {

558

return new InfrastructureAdvisorAutoProxyCreator();

559

}

560

561

// Only infrastructure advisors will be applied

562

@Bean

563

@Role(BeanDefinition.ROLE_INFRASTRUCTURE)

564

public Advisor infrastructureAdvisor() {

565

return new DefaultPointcutAdvisor(

566

new AnnotationMatchingPointcut(Repository.class),

567

new DataAccessExceptionInterceptor()

568

);

569

}

570

}

571

```