Boost Spring Performance: AOP Logging, Caching, Thread Pools & DB Optimizations
This article presents practical Spring performance optimization techniques—including AOP‑based logging, second‑level caching with @Cacheable, reducing database queries via fetch strategies, employing thread‑pool executors, and general database query tuning—to improve application speed and resource efficiency.
Environment: Spring 5.3.23. Spring is widely adopted, but without proper performance tuning it can cause slowdowns. The following examples demonstrate practical Spring performance optimizations.
1. Optimize Logging with AOP
Using Aspect‑Oriented Programming to filter log statements reduces the overhead of logging every request. An aspect defines pointcuts and advice that log only when certain conditions are met.
@Aspect
@Component
public class UserServiceAspect {
@Pointcut("execution(* query*(long))")
private void log() {}
@Before("log()")
public void logBefore(JoinPoint joinPoint) {
long userId = (int) joinPoint.getArgs()[0];
// Log only when userId is invalid
if (userId <= 0) {
log.info("queryById - start - userId: {}", userId);
}
}
@AfterReturning(pointcut = "execution(public User query*(long))", returning = "user")
public void logAfter(JoinPoint joinPoint, User user) {
// Log only when a user is found
if (user != null) {
long userId = (int) joinPoint.getArgs()[0];
log.info("queryById - end - userId={}, user info={}", userId, user);
}
}
}2. Use Second‑Level Cache
Spring’s caching abstraction can store method results in memory, avoiding repeated database access. The @Cacheable annotation marks a method as cacheable, and a CacheManager manages the cache.
@Configuration
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("user");
}
} @Service
@CacheConfig(cacheManager = "cacheManager") // inject CacheManager
public class UserService {
@Resource
private UserRepository userRepository;
@Autowired
private CacheManager cacheManager;
// Cache the result of queryById
@Cacheable(value = "user", key = "#userId")
public User queryById(long userId) {
User user = userRepository.findById(userId);
return user;
}
}3. Reduce Database Queries
Fetching related entities in a single query using a custom @Select reduces the number of SQL statements executed for each request.
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
@Select("SELECT o.*, od.* FROM Order o LEFT JOIN o.orderDetails od WHERE o.id = ?1")
Order findWithOrderDetailsByOrderId(Long orderId);
}4. Employ Thread‑Pool Executors
Using a thread‑pool executor allows concurrent processing of tasks, preventing the creation of a new thread per request and improving throughput.
@Service
public class UserService {
@Resource
private UserRepository userRepository;
private ThreadPoolExecutor pool;
@Override
public List<User> getUsers() {
int coreThreads = 10; // core thread count
int maxThreads = 20; // maximum thread count
long keepAliveTime = 60L; // seconds
ThreadPoolExecutor pool = new ThreadPoolExecutor(
coreThreads,
maxThreads,
keepAliveTime,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>());
List<User> users = userRepository.findAll();
for (final User user : users) {
pool.execute(() -> {
// TODO: process user
});
}
pool.shutdown(); // close the pool
return users;
}
}5. General Database Query Tuning
Use indexes, preferably composite indexes, to accelerate lookups.
Avoid SELECT *; query only required columns to enable covering indexes.
Apply pagination to limit the amount of data retrieved per request.
Batch operations to reduce the number of round‑trips to the database.
Utilize a connection pool to reuse connections and avoid frequent creation/destruction.
Applying these techniques helps Spring applications achieve better performance, scalability, and reliability.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
