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

aspectj-integration.mddocs/

0

# AspectJ Integration

1

2

Spring AOP provides comprehensive integration with AspectJ, supporting AspectJ pointcut expressions, @AspectJ annotations, and aspect instance management. This integration enables developers to use AspectJ's powerful expression language and annotation-based configuration while leveraging Spring's proxy-based AOP infrastructure.

3

4

## Capabilities

5

6

### AspectJ Expression Pointcuts

7

8

Pointcut implementation using AspectJ's expression language for sophisticated join point matching.

9

10

```java { .api }

11

public class AspectJExpressionPointcut implements ClassFilter, MethodMatcher, Pointcut, BeanFactoryAware, ParameterNameDiscoverer {

12

/**

13

* Set the AspectJ expression.

14

* @param expression the AspectJ expression

15

*/

16

public void setExpression(String expression);

17

18

/**

19

* Return the AspectJ expression.

20

*/

21

public String getExpression();

22

23

/**

24

* Set the parameter types, if they are known.

25

* @param types the parameter types

26

*/

27

public void setParameterTypes(Class<?>... types);

28

29

/**

30

* Set the parameter names, if they are known.

31

* @param names the parameter names

32

*/

33

public void setParameterNames(String... names);

34

35

/**

36

* Return the parameter names, if they are known, or {@code null} if not.

37

*/

38

public String[] getParameterNames();

39

40

/**

41

* Check whether this pointcut is ready to match,

42

* i.e. whether it has been configured with a complete expression.

43

*/

44

public boolean isReady();

45

46

// ClassFilter implementation

47

@Override

48

public boolean matches(Class<?> clazz);

49

50

// MethodMatcher implementation

51

@Override

52

public boolean matches(Method method, Class<?> targetClass);

53

54

@Override

55

public boolean isRuntime();

56

57

@Override

58

public boolean matches(Method method, Class<?> targetClass, Object... args);

59

60

// Pointcut implementation

61

@Override

62

public ClassFilter getClassFilter();

63

64

@Override

65

public MethodMatcher getMethodMatcher();

66

}

67

68

public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdvisor implements BeanFactoryAware {

69

/**

70

* Create a new AspectJExpressionPointcutAdvisor.

71

*/

72

public AspectJExpressionPointcutAdvisor();

73

74

/**

75

* Create a new AspectJExpressionPointcutAdvisor.

76

* @param advice the advice to use

77

* @param expression the AspectJ expression

78

*/

79

public AspectJExpressionPointcutAdvisor(Advice advice, String expression);

80

81

/**

82

* Set the AspectJ expression.

83

* @param expression the AspectJ expression

84

*/

85

public void setExpression(String expression);

86

87

/**

88

* Return the AspectJ expression.

89

*/

90

public String getExpression();

91

92

/**

93

* Set the parameter names for the pointcut.

94

* @param parameterNames the parameter names

95

*/

96

public void setParameterNames(String... parameterNames);

97

98

/**

99

* Set the parameter types for the pointcut.

100

* @param parameterTypes the parameter types

101

*/

102

public void setParameterTypes(Class<?>... parameterTypes);

103

104

@Override

105

public Pointcut getPointcut();

106

}

107

```

108

109

### AspectJ Advice Types

110

111

Spring AOP advice implementations that wrap AspectJ-style advice methods with precedence information.

112

113

```java { .api }

114

public class AspectJMethodBeforeAdvice implements MethodBeforeAdvice, AspectJPrecedenceInformation {

115

/**

116

* Create a new AspectJMethodBeforeAdvice for the given advice method.

117

* @param adviceMethod the AspectJ-style advice method

118

* @param pointcut the AspectJ expression pointcut

119

* @param aspectInstanceFactory the factory for aspect instances

120

*/

121

public AspectJMethodBeforeAdvice(Method adviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aspectInstanceFactory);

122

123

@Override

124

public void before(Method method, Object[] args, Object target) throws Throwable;

125

126

// AspectJPrecedenceInformation implementation

127

@Override

128

public String getAspectName();

129

130

@Override

131

public int getDeclarationOrder();

132

133

@Override

134

public boolean isBeforeAdvice();

135

136

@Override

137

public boolean isAfterAdvice();

138

}

139

140

public class AspectJAfterAdvice implements MethodInterceptor, AfterAdvice, AspectJPrecedenceInformation {

141

/**

142

* Create a new AspectJAfterAdvice for the given advice method.

143

* @param adviceMethod the AspectJ-style advice method

144

* @param pointcut the AspectJ expression pointcut

145

* @param aspectInstanceFactory the factory for aspect instances

146

*/

147

public AspectJAfterAdvice(Method adviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aspectInstanceFactory);

148

149

@Override

150

public Object invoke(MethodInvocation mi) throws Throwable;

151

152

// AspectJPrecedenceInformation implementation

153

@Override

154

public String getAspectName();

155

156

@Override

157

public int getDeclarationOrder();

158

159

@Override

160

public boolean isBeforeAdvice();

161

162

@Override

163

public boolean isAfterAdvice();

164

}

165

166

public class AspectJAfterReturningAdvice implements AfterReturningAdvice, AspectJPrecedenceInformation {

167

/**

168

* Create a new AspectJAfterReturningAdvice for the given advice method.

169

* @param adviceMethod the AspectJ-style advice method

170

* @param pointcut the AspectJ expression pointcut

171

* @param aspectInstanceFactory the factory for aspect instances

172

*/

173

public AspectJAfterReturningAdvice(Method adviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aspectInstanceFactory);

174

175

/**

176

* Set the name of the parameter in the advice method that receives the return value.

177

* @param name parameter name

178

*/

179

public void setReturningName(String name);

180

181

@Override

182

public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;

183

184

// AspectJPrecedenceInformation implementation methods...

185

}

186

187

public class AspectJAfterThrowingAdvice implements MethodInterceptor, AfterAdvice, AspectJPrecedenceInformation {

188

/**

189

* Create a new AspectJAfterThrowingAdvice for the given advice method.

190

* @param adviceMethod the AspectJ-style advice method

191

* @param pointcut the AspectJ expression pointcut

192

* @param aspectInstanceFactory the factory for aspect instances

193

*/

194

public AspectJAfterThrowingAdvice(Method adviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aspectInstanceFactory);

195

196

/**

197

* Set the name of the parameter in the advice method that receives the thrown exception.

198

* @param name parameter name

199

*/

200

public void setThrowingName(String name);

201

202

@Override

203

public Object invoke(MethodInvocation mi) throws Throwable;

204

205

// AspectJPrecedenceInformation implementation methods...

206

}

207

208

public class AspectJAroundAdvice implements MethodInterceptor, AspectJPrecedenceInformation {

209

/**

210

* Create a new AspectJAroundAdvice for the given advice method.

211

* @param adviceMethod the AspectJ-style advice method

212

* @param pointcut the AspectJ expression pointcut

213

* @param aspectInstanceFactory the factory for aspect instances

214

*/

215

public AspectJAroundAdvice(Method adviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aspectInstanceFactory);

216

217

@Override

218

public Object invoke(MethodInvocation mi) throws Throwable;

219

220

// AspectJPrecedenceInformation implementation methods...

221

}

222

```

223

224

### AspectJ Proxy Factory

225

226

Specialized proxy factory for creating proxies with AspectJ aspects.

227

228

```java { .api }

229

public class AspectJProxyFactory extends ProxyCreatorSupport {

230

/**

231

* Create a new AspectJProxyFactory.

232

*/

233

public AspectJProxyFactory();

234

235

/**

236

* Create a new AspectJProxyFactory.

237

* <p>Will proxy all interfaces that the given target implements.

238

* @param target the target object to be proxied

239

*/

240

public AspectJProxyFactory(Object target);

241

242

/**

243

* Add the supplied aspect instance to the chain. The type of the aspect instance

244

* supplied must be a singleton aspect. True singleton lifecycle is not honoured when

245

* using this method - the caller is responsible for managing the lifecycle of any

246

* aspects added in this way.

247

* @param aspectInstance the AspectJ aspect instance

248

*/

249

public void addAspect(Object aspectInstance);

250

251

/**

252

* Add an aspect of the supplied type to the end of the advice chain.

253

* @param aspectClass the AspectJ aspect class

254

*/

255

public void addAspect(Class<?> aspectClass);

256

257

/**

258

* Create a proxy according to this factory's settings.

259

* @return the proxy object

260

*/

261

@SuppressWarnings("unchecked")

262

public <T> T getProxy();

263

264

/**

265

* Create a proxy according to this factory's settings.

266

* @param classLoader the class loader to create the proxy with

267

* @return the proxy object

268

*/

269

@SuppressWarnings("unchecked")

270

public <T> T getProxy(ClassLoader classLoader);

271

}

272

```

273

274

### Aspect Instance Factories

275

276

Factories for managing aspect instances and their metadata.

277

278

```java { .api }

279

public interface AspectInstanceFactory {

280

/**

281

* Create an instance of this factory's aspect.

282

* @return the aspect instance (never {@code null})

283

*/

284

Object getAspectInstance();

285

286

/**

287

* Expose the aspect class loader that this factory uses.

288

* @return the aspect class loader (or {@code null} for the bootstrap loader)

289

* @see org.springframework.util.ClassUtils#getDefaultClassLoader()

290

*/

291

ClassLoader getAspectClassLoader();

292

293

/**

294

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

295

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

296

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

297

* <p>Same order values will result in arbitrary sort positions for the

298

* affected objects.

299

* @return the order value

300

* @see #HIGHEST_PRECEDENCE

301

* @see #LOWEST_PRECEDENCE

302

*/

303

int getOrder();

304

}

305

306

public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactory {

307

/**

308

* Return the AspectJ AspectMetadata for this factory's aspect.

309

* @return the aspect metadata

310

*/

311

AspectMetadata getAspectMetadata();

312

313

/**

314

* Return the best possible creation mutex for this factory:

315

* that is, an object that should be synchronized on for creation

316

* of the aspect instance.

317

* @return the mutex object (may be {@code null} for no mutex to use)

318

*/

319

Object getAspectCreationMutex();

320

}

321

322

public class SimpleAspectInstanceFactory implements AspectInstanceFactory {

323

/**

324

* Create a new SimpleAspectInstanceFactory for the given aspect class.

325

* @param aspectClass the aspect class

326

*/

327

public SimpleAspectInstanceFactory(Class<?> aspectClass);

328

329

@Override

330

public final Object getAspectInstance();

331

332

@Override

333

public ClassLoader getAspectClassLoader();

334

335

@Override

336

public int getOrder();

337

}

338

339

public class SingletonAspectInstanceFactory implements AspectInstanceFactory {

340

/**

341

* Create a new SingletonAspectInstanceFactory for the given aspect.

342

* @param aspectInstance the singleton aspect instance

343

*/

344

public SingletonAspectInstanceFactory(Object aspectInstance);

345

346

@Override

347

public final Object getAspectInstance();

348

349

@Override

350

public ClassLoader getAspectClassLoader();

351

352

@Override

353

public int getOrder();

354

}

355

356

public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInstanceFactory, BeanFactoryAware {

357

/**

358

* Create a BeanFactoryAspectInstanceFactory. AspectJ will be called to

359

* introspect to create AJType metadata using the type returned for the

360

* given bean name from the BeanFactory.

361

* @param beanFactory the BeanFactory to obtain instance(s) from

362

* @param beanName the name of the bean

363

*/

364

public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String beanName);

365

366

/**

367

* Set the name of the aspect bean. This is only used for tracing purposes,

368

* but can help debugging.

369

* @param aspectName the name to use. If not specified the bean name is used.

370

*/

371

public void setAspectName(String aspectName);

372

373

@Override

374

public Object getAspectInstance();

375

376

@Override

377

public ClassLoader getAspectClassLoader();

378

379

@Override

380

public AspectMetadata getAspectMetadata();

381

382

@Override

383

public Object getAspectCreationMutex();

384

385

@Override

386

public int getOrder();

387

}

388

```

389

390

### AspectJ Metadata Support

391

392

Classes for managing AspectJ aspect metadata and precedence information.

393

394

```java { .api }

395

public class AspectMetadata implements Serializable {

396

/**

397

* Create a new AspectMetadata instance for the given aspect class.

398

* @param aspectClass the aspect class

399

* @param aspectName the name of the aspect

400

*/

401

public AspectMetadata(Class<?> aspectClass, String aspectName);

402

403

/**

404

* Return the AspectJ type representation of this aspect class.

405

*/

406

public AjType<?> getAjType();

407

408

/**

409

* Return the aspect class.

410

*/

411

public Class<?> getAspectClass();

412

413

/**

414

* Return the aspect name.

415

*/

416

public String getAspectName();

417

418

/**

419

* Return the per clause pointcut, or {@code Pointcut.TRUE} if there is no per clause.

420

* <p>NB: This returns the value of the per clause on the aspect.

421

* If this aspect was configured as a Spring bean using BeanFactory semantics,

422

* then this will not be the same as BeanFactory semantics.

423

* In such cases {@code BeanFactoryAspectInstanceFactory} should be used.

424

*/

425

public Pointcut getPerClausePointcut();

426

427

/**

428

* Return whether the aspect is defined as "perthis" or "pertarget".

429

*/

430

public boolean isPerThisOrPerTarget();

431

432

/**

433

* Return whether the aspect is defined as "pertypewithin".

434

*/

435

public boolean isPerTypeWithin();

436

437

/**

438

* Return whether the aspect needs to be lazily instantiated.

439

*/

440

public boolean isLazilyInstantiated();

441

}

442

443

public interface AspectJPrecedenceInformation {

444

/**

445

* Return the name of the aspect (bean) in which the advice was declared.

446

*/

447

String getAspectName();

448

449

/**

450

* Return the declaration order of the advice member within the aspect.

451

*/

452

int getDeclarationOrder();

453

454

/**

455

* Return whether this is a before advice.

456

*/

457

boolean isBeforeAdvice();

458

459

/**

460

* Return whether this is an after advice.

461

*/

462

boolean isAfterAdvice();

463

}

464

```

465

466

### @AspectJ Annotation Support

467

468

Support for processing @AspectJ annotated classes and creating advisors from them.

469

470

```java { .api }

471

public interface AspectJAdvisorFactory {

472

/**

473

* Determine whether or not the given class is an aspect, as reported

474

* by AspectJ's {@link org.aspectj.lang.reflect.AjTypeSystem}.

475

* <p>Will simply return {@code false} if the supposed aspect is

476

* not an AspectJ aspect at all.

477

* @param clazz the supposed annotation-style AspectJ aspect class

478

* @return whether or not this class is recognized by AspectJ as an aspect class

479

*/

480

boolean isAspect(Class<?> clazz);

481

482

/**

483

* Is the given class a valid AspectJ aspect class?

484

* @param aspectClass the aspect class to validate

485

* @throws AopConfigException if the class is an invalid aspect

486

* (which can never be legal)

487

* @throws NotAnAtAspectException if the class is not an aspect at all

488

* (which may or may not be legal, depending on the context)

489

*/

490

void validate(Class<?> aspectClass) throws AopConfigException;

491

492

/**

493

* Build Spring AOP Advisors for all annotated At-AspectJ methods

494

* on the specified aspect instance.

495

* @param aspectInstanceFactory the aspect instance factory

496

* (not the aspect instance itself in order to avoid eager instantiation)

497

* @return a list of advisors for this class

498

*/

499

List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory);

500

501

/**

502

* Build a Spring AOP Advisor for the given AspectJ advice method.

503

* @param candidateAdviceMethod the candidate advice method

504

* @param aspectInstanceFactory the aspect instance factory

505

* @param declarationOrder the declaration order within the aspect

506

* @param aspectName the name of the aspect

507

* @return {@code null} if the method is not an AspectJ advice method

508

* or if it is a pointcut that will be used by other advice but will not

509

* create a Spring advice in its own right

510

*/

511

Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,

512

int declarationOrder, String aspectName);

513

}

514

515

public class ReflectiveAspectJAdvisorFactory implements AspectJAdvisorFactory, Serializable {

516

@Override

517

public boolean isAspect(Class<?> clazz);

518

519

@Override

520

public void validate(Class<?> aspectClass) throws AopConfigException;

521

522

@Override

523

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory);

524

525

@Override

526

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,

527

int declarationOrder, String aspectName);

528

}

529

```

530

531

### Support Classes

532

533

Additional support classes for AspectJ integration.

534

535

```java { .api }

536

public class TypePatternClassFilter implements ClassFilter {

537

/**

538

* Create a new TypePatternClassFilter for the given AspectJ type pattern.

539

* @param typePattern the AspectJ type pattern

540

*/

541

public TypePatternClassFilter(String typePattern);

542

543

@Override

544

public boolean matches(Class<?> clazz);

545

}

546

547

public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint, JoinPoint.StaticPart {

548

/**

549

* Create a new MethodInvocationProceedingJoinPoint, wrapping the given

550

* Spring ProxyMethodInvocation object.

551

* @param methodInvocation the Spring ProxyMethodInvocation object

552

*/

553

public MethodInvocationProceedingJoinPoint(ProxyMethodInvocation methodInvocation);

554

555

@Override

556

public Object proceed() throws Throwable;

557

558

@Override

559

public Object proceed(Object[] args) throws Throwable;

560

561

// JoinPoint implementation methods...

562

@Override

563

public String toShortString();

564

565

@Override

566

public String toLongString();

567

568

@Override

569

public Object getThis();

570

571

@Override

572

public Object getTarget();

573

574

@Override

575

public Object[] getArgs();

576

577

@Override

578

public Signature getSignature();

579

580

@Override

581

public SourceLocation getSourceLocation();

582

583

@Override

584

public String getKind();

585

586

@Override

587

public JoinPoint.StaticPart getStaticPart();

588

}

589

```

590

591

## Usage Examples

592

593

### AspectJ Expression Pointcuts

594

595

```java

596

// Create pointcut with AspectJ expression

597

AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();

598

pointcut.setExpression("execution(* com.example.service.*Service.*(..))");

599

600

// Use in advisor

601

AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();

602

advisor.setExpression("execution(* com.example.service.*Service.*(..))");

603

advisor.setAdvice(new LoggingInterceptor());

604

605

// Complex expressions

606

pointcut.setExpression(

607

"execution(public * com.example.service.*Service.*(..)) && " +

608

"@annotation(org.springframework.transaction.annotation.Transactional)"

609

);

610

```

611

612

### Using AspectJ Proxy Factory

613

614

```java

615

// Create AspectJ-based proxy

616

AspectJProxyFactory factory = new AspectJProxyFactory(targetObject);

617

618

// Add aspect instance

619

@Aspect

620

class LoggingAspect {

621

@Around("execution(* com.example.service.*.*(..))")

622

public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {

623

long start = System.currentTimeMillis();

624

Object result = joinPoint.proceed();

625

long executionTime = System.currentTimeMillis() - start;

626

System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");

627

return result;

628

}

629

}

630

631

factory.addAspect(new LoggingAspect());

632

MyService proxy = factory.getProxy();

633

634

// Or add aspect class

635

factory.addAspect(LoggingAspect.class);

636

```

637

638

### Creating Custom AspectJ Advice

639

640

```java

641

public class CustomAspectJAdvice implements MethodInterceptor, AspectJPrecedenceInformation {

642

private final String aspectName;

643

private final int declarationOrder;

644

645

public CustomAspectJAdvice(String aspectName, int declarationOrder) {

646

this.aspectName = aspectName;

647

this.declarationOrder = declarationOrder;

648

}

649

650

@Override

651

public Object invoke(MethodInvocation invocation) throws Throwable {

652

// Custom advice logic here

653

System.out.println("Custom AspectJ advice executing for: " + invocation.getMethod().getName());

654

return invocation.proceed();

655

}

656

657

@Override

658

public String getAspectName() {

659

return aspectName;

660

}

661

662

@Override

663

public int getDeclarationOrder() {

664

return declarationOrder;

665

}

666

667

@Override

668

public boolean isBeforeAdvice() {

669

return false;

670

}

671

672

@Override

673

public boolean isAfterAdvice() {

674

return true;

675

}

676

}

677

```

678

679

### Working with Aspect Metadata

680

681

```java

682

// Examine aspect metadata

683

Class<?> aspectClass = MyAspect.class;

684

AspectMetadata metadata = new AspectMetadata(aspectClass, "myAspect");

685

686

System.out.println("Aspect name: " + metadata.getAspectName());

687

System.out.println("Aspect class: " + metadata.getAspectClass().getName());

688

System.out.println("Is per-this or per-target: " + metadata.isPerThisOrPerTarget());

689

System.out.println("Requires lazy instantiation: " + metadata.isLazilyInstantiated());

690

691

// Get per-clause pointcut

692

Pointcut perClause = metadata.getPerClausePointcut();

693

if (perClause != Pointcut.TRUE) {

694

System.out.println("Has per-clause pointcut");

695

}

696

```