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 timeweaveInto 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