This is a pure example blog. There are very few examples of AspectJ on the web. Many of the blogs are about AOP concepts and AspectJ from the perspective of the AspectJ language itself. There is no need to learn more about AspectJ from the language itself. If you don’t understand AOP ideas, please refer to my blog to talk about Spring AOP!
This article will start with AspectJ in Spring.
First understand a point, AOP thought implementation framework or library there are many, the most famous is nothing more than AspectJ, Cglib, JDK dynamic proxy three, in the final analysis they are the use of proxy this design pattern, the difference lies in the following table:
The name of the | The agent type | The basic principle of | features |
---|---|---|---|
AspectJ | Static agent | The proxy class is generated at compile time, but the corresponding facets are generated at compile timeweave Into the proxy class |
|
Cglib | A dynamic proxy | Proxy classes are generated dynamically at run time, and the underlying bytecode processing framework ASM is used to transform bytecode and generate new classes | Cglib can dynamically delegate classes to compensate for JDK dynamic proxies that can only delegate interfaces |
JDK dynamic proxy | A dynamic proxy | Proxy classes are generated dynamically at run time, and a Native method is invoked at the source level | Proxy-only interface |
For more information about the Cglib proxy, read another blog post on the use of the Cglib proxy
Use AspectJ in Spring
1. Enable aspectJ annotation support in XML
applicationContext.xml
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
Copy the code
2. Declare the section class
@Aspect
@Component
public class ExecutionAspect {
@Before("execution(* wokao666.club.myapp.aspectJ.*.before*(..) )")
public void doBefore(JoinPoint joinPoint) throws Throwable {
System.err.println("This is a pre-notification that is executed before the method is called!!");
}
@After("execution(* wokao666.club.myapp.aspectJ.*.after*(..) )")
public void doAfter(JoinPoint joinPoint) throws Throwable {
System.err.println("This is a post-notification that is executed after the method call!!");
}
@Around("execution(* wokao666.club.myapp.aspectJ.*.around*(..) )")
public void doAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.err.println("This is a wrap around notification that is executed before and after a method call!!");
System.err.println("Pre-execution");
joinPoint.proceed();
System.err.println("After execution"); }}Copy the code
Execution indicates the join point type. The first * indicates the intercepted method but return value type, and the * indicates the return value of any type. The second part wokao666. Club. Myapp. AspectJ. * before * (..) Said to wokao666. Club. Myapp. AspectJ package under any kind of way to all begin with before.
3. Test classesMain.java
public class Main {
private static ClassPathXmlApplicationContext ctx = null;
public static void main(String[] args) {
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
TestMethod test = (TestMethod) ctx.getBean("bean");
test.before("before");
System.err.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
test.after("after");
System.err.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
test.around("around");
}
Copy the code
4, the bean class
@Component("bean")
public class TestMethod {
public void before(String name) {
System.err.println("the param Name is " + name);
}
public void after(String name) {
System.err.println("the param Name is " + name);
}
public void around(String name) {
System.err.println("the param Name is "+ name); }}Copy the code
pom.xml
<dependency> <groupId>aspectj</groupId> <artifactId> aspectJrt </artifactId> <version>1.5.4</version> </dependency> < the dependency > < groupId > org. Aspectj < / groupId > < artifactId > aspectjweaver < / artifactId > < version > 1.9.1 < / version > </dependency>Copy the code
Execution Result:
This is a pre-notification that is executed before the method is called!! The param Name is before = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = the param Name is after this notice is a rear, Is executed after a method call!! = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = this is surrounded by a notice, in the before and after the method call will perform!!! Before execution the param Name is around after executionCopy the code
Second, interception implementation based on custom annotations
We sometimes use custom annotations to identify our business methods. AspectJ intercepts annotation-based implementations as described below. The difference is simply the pointcut expression.
1. Create a custom annotationRpcService
/** * Remote service annotation, */ @documented @Retention(RetentionPolicy.runtime) @target (value = {ElementType.METHOD, ElementType.TYPE }) public @interface RpcService { }Copy the code
2. Declare the business method
@Component("bean")
public class TestMethod {
@RpcService
public void around(String name) {
System.err.println("the param Name is "+ name); }}Copy the code
Declare the section class
@Aspect
@Component
public class AnnotationAspect {
@Around("@annotation(wokao666.club.myapp.annotation.RpcService)")
public void doAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.err.println("This is a wrap around notification that is executed before and after a method call!!");
System.err.println("Pre-execution");
joinPoint.proceed();
System.err.println("After execution"); }}Copy the code
4. Test classes
public class Main {
private static ClassPathXmlApplicationContext ctx = null;
public static void main(String[] args) {
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
TestMethod test = (TestMethod) ctx.getBean("bean");
test.around("around"); }}Copy the code
5. Execution results
This is a wrap around notification that is executed before and after a method call!! Before execution the param Name is around after executionCopy the code
Graduated, how to feel a bit impatient, steady steady!
If we want to get the return value of the cut method, then we can use
MethodSignature si = (MethodSignature) joinPoint.getSignature();
System.err.println(si.getReturnType());
Copy the code