Backend Development 8 min read

Master Spring AOP’s @DeclareParents: Dynamic Interface Injection in Spring Boot 3

This article explains how Spring AOP’s @DeclareParents introduces new interfaces to proxied beans at runtime, walks through defining interfaces, implementations, aspect configuration, testing with Spring Boot 3, and also covers perthis and pertarget aspect instantiation models for fine‑grained lifecycle control.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master Spring AOP’s @DeclareParents: Dynamic Interface Injection in Spring Boot 3

Spring AOP provides a special type enhancement called "Introductions" (implemented via @DeclareParents ) that allows an aspect to dynamically introduce new interfaces to a proxied object, enabling the object to implement methods declared by those interfaces at runtime.

1. Introducing Interfaces

Define the interface that the target class should implement.

<code>public interface DAO {
  void remove();
}</code>

Implement the interface.

<code>public class DefaultDAO implements DAO {
  @Override
  public void remove() {
    System.out.println("默认删除功能");
  }
}</code>

Create the aspect using @DeclareParents to bind the interface to the target class.

<code>@Aspect
public class LogAspect {
  @Pointcut("@annotation(log)")
  private void recordLog(Log log) {}

  // Bind PersonService to DAO interface
  @DeclareParents(value = "com.pack.aop.PersonService", defaultImpl = DefaultDAO.class)
  private DAO dao;

  @Around("recordLog()")
  public Object aroundLog(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("日志执行前...");
    Object ret = pjp.proceed();
    System.out.println("日志执行后...");
    return ret;
  }
}</code>

Define the service class.

<code>@Service
public class PersonService {
  public void save() {
    System.out.println("保存Person对象");
  }
}</code>

Test the behavior.

<code>@SpringBootTest
public class AppTest {
  private final PersonService ps;
  public AppTest(PersonService ps) { this.ps = ps; }

  @Test
  public void testSave() {
    ps.save();
    if (ps instanceof DAO dao) {
      dao.remove();
    }
  }
}</code>

Output:

<code>日志执行前...
保存Person对象
日志执行后...
默认删除功能</code>

2. Aspect Instantiation Models

Spring AOP supports perthis, pertarget, and pertypewithin models. The perthis model creates a separate aspect instance for each target object that matches the pointcut; pertarget does the same for each unique target object.

Example of perthis model:

<code>@Component
@Scope("prototype")
@Aspect("perthis(execution(* com.pack.aop.DAO.*(..)))")
public class LogAspect {
  @Before("bean(*Service)")
  public void beforeLog(JoinPoint jp) {
    System.out.println("before 记录日志 - " + this);
  }
}</code>

Define business objects implementing DAO.

<code>public interface DAO { void save(); }

public class PersonService implements DAO {
  public void save() { System.out.println("保存Person对象"); }
}

public class StudentService implements DAO {
  public void save() { System.out.println("保存Student对象"); }
}</code>

Test both services.

<code>@SpringBootTest
public class AppTest {
  @Resource private PersonService ps;
  @Resource private StudentService ss;

  @Test
  public void testAll() {
    ps.save();
    System.out.println("===============" );
    ss.save();
  }
}</code>

Output:

<code>before 记录日志 - com.pack.aop.LogAspect@3ed242a4
保存Person对象
====================
before 记录日志 - com.pack.aop.create.LogAspect@73a2e526
保存Student对象</code>

These models are rarely needed unless fine‑grained control over aspect lifecycle is required.

JavaSpring BootSpring AOPAspectJDynamic Interface
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.