Reputation: 63
Can anyone please explain the difference between Aspects, concerns and cross-cutting concerns in Spring AOP with example? I have gone through a lot of tutorial sites but I didn't get any good explanation.
Upvotes: 6
Views: 1505
Reputation: 845
Upvotes: 0
Reputation: 8017
Don't worry, it's pretty simple, and your question, once answered, unlocks everything you need to know about AOP, so it's a great question! :)
TL/DR; In AOP, a concern cannot be distributed by an aspect, and a cross-cutting concern can, and that's all an aspect does in the first place:
"Aspects let you distribute cross-cutting concerns from a single place in code"!
The reason AOP was formulated is because people realized that in programming, there is a special type of concern called a "cross-cutting concern", and it's really hard to do these things in a single place. So they came up with "aspects", to encapsulate them and think about the problem differently. So now, with AOP (which are just aspects really), you can now do these slippery "cross-cutting concerns" in a single place too, just like you can normal concerns. That's the fundamental reasoning and purpose for AOP, and nothing else. That's all it is!
Here is a more detailed breakdown between the two types of concerns...
Concerns (aka "core-concerns")
Cross-cutting Concerns
Detailed example
If you wrote an API in AOP that took and image and returned vectors representing it for downstream processing in your platform, core concerns would be:
Most of these concerns can be injected into your application through a configuration object (except for #5 and #6). It's totally ripe for optimization. Let's reduce this thing to maybe 20 lines of code if we can!
In contrast, cross-cutting concerns are something that can only be applied in multiple places. Oh crap... we have to do logging, we have to format the input, we have to format the output... and shoot, we have to do these things in multiple places... that means we have to repeat ourselves... write the same line more than once... This is going to get Ugly... Aha! This is where AOP comes in!
Aspects
Your question is so wonderful because AOP doesn't force you to do things right; it just lets you. Most people miss the key point of AOP; Do the things you can't optimize into a single place, into a single place! In fact most AOP code I read is poor. Probably 9 out of 10 projects in AOP are just fundamentally missing the point. Most people I teach AOP don't get it. Your question really stabs at it's heart! Lets now cover aspects...
Aspects let you deeply cut into the SOC principle (Separation of Concerns) by instead of calling your "cross-cutting" concerns, like repeted function calls to logging and formatting in the same way you would call your regular concerns, you instead abstract them into aspects.
There are various ways to do this, mainly 3, but whatever way people dream up, the ways themselves are referred to as "advice".
The main 3 types of advice are:
Example Code
Let's define a service...
package com.example.demo.service;
public interface UserService {
void createUser(String name);
}
// Note: No AOP yet! :)
Let's implement the service...
package com.example.demo.service.impl;
import com.example.demo.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Override
public void createUser(String name) {
// Core business logic to create a user goes here...
System.out.println("Creating user: " + name);
}
}
// Note: Still no AOP yet! :)
Now lets create an aspect for logging...
package com.example.demo.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
// Here is our aspect... This is all called "advice"...
// Here we define a "pointcut", which in this case is just saying whenever "UserService.createUser" is executed...
@Pointcut("execution(* com.example.demo.service.UserService.createUser(..))")
public void createUserPointcut() {}
// Here we're saying do something before that pointcut...
@Before("createUserPointcut()")
public void logBeforeCreateUser(JoinPoint joinPoint) {
System.out.println("Before creating user: " + joinPoint.getSignature().getName());
}
// Here we're saying do something after that pointcut...
@AfterReturning("createUserPointcut()")
public void logAfterReturningCreateUser(JoinPoint joinPoint) {
System.out.println("After successfully creating user: " + joinPoint.getSignature().getName());
}
}
For completeness, you have to enable Auto-Proxy support (nothing of concern here, just particular to AspectJ)...
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
// This class can be empty if you're just enabling AspectJ auto-proxy support
}
Isn't this just a hook?
Yes it is! But it's a hook with extra steps, and those steps yield something useful. In fact AOP can also be thought of as proxies or, at least at some level, middleware (although middleware is considered an antipattern for good reason now).
Lifecycle hooks are similar to AOP in that, in the framework you're using that includes hooks, if they thought of hooks deeply, you can often shift most of your cross-cutting concerns into hooks! However, AOP implementations, like AspectJ, provide these more fundamental hooks in your code, so you can create any lifecycle hook you want.
Do I have to use AspectJ / Spring?
Heck no! In fact, the whole point of AOP is to reduce lines of code! So, AspectJ/Spring, and Java for that matter, are actually poor implementations of AOP, they're just the most known.
"We have 1.7 million lines of code!" "Sure, but in AOP it would be 30k."
There is an AOP implementation for almost every language. Check out Aspect.js for JavaScript, or search for your favorite language and get optimizing!
Is Aspect Oriented Programming the best way to program now days?
Yes and no. Fundamentally, programming is all about configuration, logic, and branching, and then encoding those things. No matter what language you use, you're just doing those 3 things, and the 4th thing, encoding, is where AOP tries to improve our lives.
AOP just helps you separate your cross-cutting concerns into aspects.
However, You don't actually need to implement this in code (encoding). You can do it in your config more effecently, and bake it into your platform. This is actually how DNA works; competent layers of configuration, instead of actually encoding logic.
That is one step above AOP; it's perhaps AOA (Aspect Oriented Architecture) or "Competent Substrates", and probably even easier to build than AOP code, and doesn't require you learn a new way of coding.
Since you've started down this rabbithole of optimization and abstraction... why not take AOP a step further and try to address SOC at a deeper level... at your platform level, at the settings level? What would things look like if you incorporated aspects, i.e. advice, into your configuration using layered settings?
Platform-level AOP, or perhaps AOA/Competent substrates, is a much nicer way to implement AOP, because SOC occurs in settings, which gives you a nice clean implementation layer, that is, your business logic doesn't need to implement AOP in the first place; it's been done ahead of time.
What this results in is many encoding tasks that traditionally require logic, simply don't even need to exist.
Since this is the route nature takes, and all known life follows it (through the use of codons and DNA/RNA to simply encode layers that are implemented in different orders), this is perhaps the best way (but we may even find something better some day!).
This movement I'm talking about is very new and is called "configuration as code" and similar. Some developers, in 2024, are referring to this as "competent substrates", including Michael Leven, a prolific engineer who is applying software to life. You can watch his Lex Friedman podcast where he talks about this in detail here: https://www.youtube.com/watch?v=p3lsYlod5OU
Upvotes: 0