Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

AOP Proxy Creation in Spring

Spring AOP uses proxies to implement aspects, allowing the interception of method calls and the application of advice. This guide covers key concepts and steps for understanding and creating AOP proxies in Spring, including proxy types, proxy creation, and configuring proxy behavior.

Key Concepts of AOP Proxy Creation

  • Proxy: An object created by the AOP framework to implement advice.
  • JDK Dynamic Proxy: A proxy created for interfaces using Java's built-in dynamic proxy mechanism.
  • CGLIB Proxy: A proxy created for classes using the CGLIB library.
  • Target Object: The object being proxied, also known as the advised object.
  • Advised Object: The target object that is wrapped by one or more proxies.

Proxy Types

Spring AOP supports two types of proxies:

  • JDK Dynamic Proxies: Used to create proxies for interfaces.
  • CGLIB Proxies: Used to create proxies for classes.

Example: JDK Dynamic Proxy

// UserService.java
package com.example.myapp.service;

public interface UserService {
    void addUser(String username, String password);
}
// UserServiceImpl.java
package com.example.myapp.service;

import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Override
    public void addUser(String username, String password) {
        // Add user logic
    }
}

Example: CGLIB Proxy

// UserService.java
package com.example.myapp.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {

    public void addUser(String username, String password) {
        // Add user logic
    }
}

Creating Proxies

Spring AOP automatically creates proxies for beans annotated with @Aspect. The type of proxy created depends on whether the target class implements an interface.

Example: LoggingAspect.java

// LoggingAspect.java
package com.example.myapp.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.myapp.service.*.*(..))")
    public void logBeforeMethod() {
        System.out.println("A method is about to be executed.");
    }
}

Configuring Proxy Behavior

Configure proxy behavior in your Spring Boot application by adding the @EnableAspectJAutoProxy annotation to your main application class:

Example: Application.java

// Application.java
package com.example.myapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true) // Forces use of CGLIB proxies
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Using Proxies in Your Application

Use the proxies in your service layer to log method executions:

Example: UserService.java

// UserService.java
package com.example.myapp.service;

import com.example.myapp.model.User;
import com.example.myapp.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional(readOnly = true)
    public List findAllUsers() {
        return userRepository.findAll();
    }

    @Transactional(readOnly = true)
    public Optional findUserById(Long id) {
        return userRepository.findById(id);
    }

    @Transactional
    public User saveUser(User user) {
        return userRepository.save(user);
    }

    @Transactional
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
}

Testing Spring AOP Proxies

Test your Spring AOP proxy setup to ensure it works as expected:

Example: UserServiceTests.java

// UserServiceTests.java
package com.example.myapp;

import com.example.myapp.model.User;
import com.example.myapp.repository.UserRepository;
import com.example.myapp.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@SpringBootTest
public class UserServiceTests {

    @Autowired
    private UserService userService;

    @MockBean
    private UserRepository userRepository;

    @Test
    public void testAddUser() {
        User user = new User();
        user.setId(1L);
        user.setUsername("testuser");
        user.setPassword("password");

        when(userRepository.save(user)).thenReturn(user);

        userService.addUser("testuser", "password");
        verify(userRepository).save(user);
    }
}

Key Points

  • Proxy: An object created by the AOP framework to implement advice.
  • JDK Dynamic Proxy: A proxy created for interfaces using Java's built-in dynamic proxy mechanism.
  • CGLIB Proxy: A proxy created for classes using the CGLIB library.
  • Target Object: The object being proxied, also known as the advised object.
  • Advised Object: The target object that is wrapped by one or more proxies.
  • Spring AOP supports two types of proxies: JDK Dynamic Proxies and CGLIB Proxies.
  • Spring AOP automatically creates proxies for beans annotated with @Aspect.
  • Configure proxy behavior in your Spring Boot application by adding the @EnableAspectJAutoProxy annotation.
  • Use the proxies in your service layer to log method executions.
  • Test your Spring AOP proxy setup to ensure it works as expected.

Conclusion

Spring AOP uses proxies to implement aspects, allowing the interception of method calls and the application of advice. By understanding and creating AOP proxies in Spring, including JDK Dynamic Proxies and CGLIB Proxies, you can effectively manage cross-cutting concerns in your Spring Boot application. Happy coding!