
Play Store Application link – Spring Framework in 9 steps – Apps on Google Play
Understanding AOP (Aspect-Oriented Programming) in Spring
Github project link (Xml based) – https://github.com/kuldeep101990/SpringAOPXml
Github project link (Annotation based) – https://github.com/kuldeep101990/SpringAOPAnnotation
1- Aspect
An Aspect is a class that defines common behaviors (advices) to be applied at specific points (join points) in your application. It can be configured via XML or using Spring’s AspectJ integration.
2- Join Point
A Join Point is a specific point in the execution of your application where an aspect can be applied. Spring primarily supports method execution as join points.
Example:
public class UserServiceImpl implements UserService {
public void addUser(User user) {
// Implementation code to add a user
}
}
// Here, the execution of addUser() is a join point where an aspect can be applied.
3- Advice
Advice is the action taken at a join point. It can run before, after, or around method execution.
Example of Before Advice:
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))") // Match any method in service package
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before " + joinPoint.getSignature().getName() + " method is called");
}
}
// logBefore() logs a message before the matched method executes.
4- Target Object
The Target Object is the object being advised by aspects. In Spring, this is usually a proxy object.
Example:
@Configuration
@EnableAspectJAutoProxy // Enable AspectJ proxying
public class AppConfig {
@Bean
public LoggingAspect loggingAspect() {
return new LoggingAspect();
}
@Bean
public UserService userService() {
return new UserServiceImpl(); // Target object
}
}
5- Weaving
Weaving is the process of linking aspects with target objects to create advised proxy objects. This occurs at runtime in Spring.
Example of Weaving:
// Same AppConfig as before enables weaving of aspects with the UserService
Types of Advice
- Before Advice:
@Before("execution(* com.example.UserService.addUser(..))")
public void beforeAddUserAdvice() {
System.out.println("Before adding a user...");
}
- After Returning Advice:
@AfterReturning("execution(* com.example.UserService.getUser(..))")
public void afterGetUserAdvice() {
System.out.println("After getting a user...");
}
- After Throwing Advice:
@AfterThrowing(value="execution(* com.example.UserService.deleteUser(..))", throwing="ex")
public void afterDeleteUserAdvice(Throwable ex) {
System.out.println("Exception during delete: " + ex.getMessage());
}
- After Advice (Finally):
@After("execution(* com.example.UserService.*(..))")
public void afterUserServiceAdvice() {
System.out.println("After UserService method call...");
}
- Around Advice:
@Around("execution(* com.example.UserService.getAllUsers(..))")
public Object aroundGetAllUsersAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before getting all users...");
Object result = joinPoint.proceed(); // Proceed with the original method
System.out.println("After getting all users...");
return result; // Return the result
}
Integrating AOP with Logging
Without IoC
public class SimpleSpellChecker implements SpellChecker {
public void checkSpelling() {
System.out.println("Inside checkSpelling method.");
Logger.getLogger(SimpleSpellChecker.class.getName()).info("Starting checkSpelling...");
}
}
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor() {
spellChecker = new SimpleSpellChecker(); // Manual instantiation
}
public void spellCheck() {
spellChecker.checkSpelling();
Logger.getLogger(TextEditor.class.getName()).info("Finished spellCheck...");
}
}
With IoC
@Component
public class SimpleSpellChecker implements SpellChecker {
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling method.");
}
}
@Component
public class TextEditor {
private SpellChecker spellChecker;
@Autowired // Spring automatically injects the dependency
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Starting method execution: " + joinPoint.getSignature().getName());
}
@After("execution(* com.example.*.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("Finishing method execution: " + joinPoint.getSignature().getName());
}
}
Conclusion
Using AOP in Spring allows for modular and maintainable code by separating cross-cutting concerns like logging. This makes it easier to manage and apply behaviors across various components without changing their source code.
Other AOP Features
1- Caching
Use AOP to cache the results of expensive method calls.
@Aspect
@Component
public class CachingAspect {
private Map<String, Object> cache = new HashMap<>();
@Around("execution(* com.example.service.*.*(..))")
public Object cacheResult(ProceedingJoinPoint joinPoint) throws Throwable {
String key = joinPoint.getSignature().toString();
if (cache.containsKey(key)) {
return cache.get(key); // Return cached result
}
Object result = joinPoint.proceed(); // Proceed with method execution
cache.put(key, result); // Cache the result
return result;
}
}
2- Transactions
Manage transactions without cluttering business logic.
@Aspect
@Component
public class TransactionAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object manageTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Transaction started.");
try {
Object result = joinPoint.proceed(); // Proceed with method execution
System.out.println("Transaction committed.");
return result;
} catch (Exception e) {
System.out.println("Transaction rolled back.");
throw e; // Handle exception
}
}
}
3- Exception Handling
Centralize exception handling logic.
@Aspect
@Component
public class ExceptionHandlingAspect {
@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex")
public void handleException(Throwable ex) {
System.out.println("Exception occurred: " + ex.getMessage());
// Additional logging or handling logic here
}
}
4- Performance Monitoring
Measure method execution times.
@Aspect
@Component
public class PerformanceMonitoringAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object monitorPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed(); // Proceed with method execution
long duration = System.currentTimeMillis() - start;
System.out.println("Execution time: " + duration + " ms");
return result;
}
}
5- Security
Apply security checks across methods.
@Aspect
@Component
public class SecurityAspect {
@Before("execution(* com.example.service.*.*(..))")
public void checkSecurity() {
// Implement security checks here
System.out.println("Security check passed.");
}
}
6- Validation
Ensure input data validity.
@Aspect
@Component
public class ValidationAspect {
@Before("execution(* com.example.service.*.*(..)) && args(input)")
public void validateInput(String input) {
if (input == null || input.isEmpty()) {
throw new IllegalArgumentException("Input cannot be null or empty.");
}
}
}
These code snippets demonstrate how to implement common AOP features using Spring, promoting better code organization and separation of concerns.
Hi there, just became alert to your blog through Google,and found that it is truly informative. I am gonna watch outfor brussels. I’ll be grateful if you continue this in future.Lots of people will be benefited from your writing.Cheers!
Thanks for your fascinating article. One other problem is that mesothelioma is generally the result of the inhalation of material from asbestos fiber, which is a dangerous material. Its commonly viewed among staff in the engineering industry who definitely have long contact with asbestos. It is caused by residing in asbestos insulated buildings for an extended time of time, Genetic makeup plays a huge role, and some persons are more vulnerable on the risk in comparison with others.
Hiya, I’m really glad I’ve found this information. Nowadays bloggers publish just about gossips and net and this is actually annoying. A good site with exciting content, that’s what I need. Thanks for keeping this web site, I’ll be visiting it. Do you do newsletters? Cant find it.
I am very happy to read this. This is the type of manual that needs to be given and not the random misinformation that is at the other blogs. Appreciate your sharing this best doc.
I was suggested this blog by my cousin. I am not sure whether or not this submit is written through him as no one else realize such distinctive approximately my trouble. You’re incredible! Thanks!