Introduction to AOP programming and its use in Spring framework

Introduction to AOP programming and its use in Spring framework


Well, I have n’t been to my blog recently and found that there are quite a lot of tourists :), I have been learning the ssh framework from a while ago (strut2 and hibernate have been done), the javaweb framework is still quite a lot, now ssm seems to be more popular However, since there is an ssh book in hand and knowledge of frameworks that I have not learned, I will start with ssh. In those two days, I learned aop for aspect-oriented programming, so I did not forget to write an article on my blog. It can also be considered to consolidate your knowledge.

aop programming:
AOP and OOP complement each other. Object-oriented programming (OOP) decomposes the program into objects at various levels; aspect-oriented programming (AOP) decomposes the program into various aspects during the running of the program. It can be said that OOP considers the program structure from a static perspective and AOP considers it from a dynamic perspective.

AOP is not coupled with a specific class. Has two characteristics: 1. Good isolation between each step 2. Source code independence.
Some terms of AOP:
1. Aspect: The aspect is used to organize multiple advices, which are defined in the aspect.
2. Join point (joinpoint): a clear point in the program execution process, in spring, the connection point is always a method call.
3. Enhanced processing (advice): The AOP framework performs enhanced processing at specific entry points.
4. Pointcut (pointcut): You can insert a connection point for enhanced processing.


OK! Next, let's demonstrate the code. Examples are always better than empty knowledge.

This example uses annotation-based methods, in addition to XML-based.
First post the two javabeans necessary for the instance

package Before;
//定义一个hello接口
public interface Hello {
//hello的两个方法
    public void foo();
    public int addUser(String name ,String pass);
}
package Before;

import org.springframework.stereotype.Component;
//注解component指定此为id为hello的bean
//实现接口并实现方法
@Component("hello")
public class HelloImpl implements Hello {

    @Override
    public void foo() {
        System.out.println("执行hello主键的foo方法");
    }

    @Override
    public int addUser(String name,String pass) {
        System.out.println("执行hello组键的adduser组键"+name);
        return 20;
    }

}

1. Define before enhancement processing
Define a section and define a before enhancement processing:

package Before;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

//定义一个切面
@Aspect
public class AuthAspect {

    //所有方法的执行作为切入点
    //括号中的是切入点表达式,文章最后进行介绍
    @Before("execution(* Before.*.*(..))")
    public void authority(){
        System.out.println("模拟进行权限检查");
    }
}

The following is the spring configuration file:

<!--beans.xml spring的配置文件 -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
    <!-- 自动搜索Bean组件 自动搜索切面类 -->
    <context:component-scan base-package="Before">
        <context:include-filter type="annotation"
            expression="org.aspectj.lang.annotation.Aspect"/>
    </context:component-scan>
    <!-- 启动@AspectJ支持 -->
    <aop:aspectj-autoproxy/>
</beans>

Ok, next we write a test class

package Before;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AspectTest {
    public static void main(String[] args) {
                // 创建Spring容器
                ApplicationContext ctx = new
                    ClassPathXmlApplicationContext("beans.xml");
                Hello hello = ctx.getBean("hello" , Hello.class);
                hello.foo();
                hello.addUser("孙悟空" , "7788");
    }
}

All the above steps all done, run the following results
Write a picture description here
comparing the results we do not AOP process:
Write a picture description here
the results it is clear that this is the role aop, based on no changes to the source code, the source code enhancement processing.


2. AfterReturning enhanced processing
AfterReturning has attribute values ​​that specify formal parameter names, and the return restriction target method must have these two formal parameters.
Not much to say, post code

package AfterReturning;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class LogAspect {
    @AfterReturning(returning="rvt", pointcut="execution(* Before.*.*(..)) && args(pass,name)")
    //声明rvt时指定的类型会限制目标方法必须有返回值或者没有返回值
    public void log(Object rvt,String pass,String name){
        System.out.println("第一个参数"+pass);
        System.out.println("第二个参数"+name);
        System.out.println("获取目标方法的返回值"+rvt);
        System.out.println("模拟记录日志功能。。。");
    }
}

Results (this result plus the result after before processing):
Write a picture description here
See the difference.


Afterthrowing enhanced processing

package AfterThrowing;

import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class RepairAspect {

    @AfterThrowing(throwing="ex",pointcut="execution(* Before.*.*(..))")
    public void doRecoveryActions11(Throwable ex){
        System.out.println("目标方法抛出的异常"+ex);
        System.out.println("模拟advice对异常的修复....");
    }
}

Time to write the helloimpl class above

package Before;

import org.springframework.stereotype.Component;

@Component("hello")
public class HelloImpl implements Hello {

    @Override
    public void foo() {
        System.out.println("执行hello主键的foo方法");
    }

    @Override
    public int addUser(String name,String pass) {
        System.out.println("执行hello组键的adduser组键"+name);
        if(name.length()<=3||name.length()>=10){
            throw new IllegalArgumentException("name的参数必须大于3小于10");
        }
        return 20;
    }

}

Class is added to the coated section of the xml file, the following results
Write a picture description here
can be seen, the enhancement processing function.


Time issue, after enhancement processing will not be mentioned, it is very simple, similar to before, except that one is before the target method and one is after.


Around enhanced processing

Post code, more than two points, a little sleepy,

package Around;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class TxAspect{

    @Around("execution(* Before.*.*(..))")
    public Object processTx (ProceedingJoinPoint jp) throws Throwable{
        System.out.println("执行目标方法之前,模拟开始事务.....");
        //获取目方法原始的调用参数
        Object [] args=jp.getArgs();
        if(args!=null&&args.length>1){
            //修改目标方法调用参数的第一个参数
            args[0] ="【增加的前缀】"+args[0];
        }
        //以改变后的参数去执行目标方法,并保存目标方法返回的执行值
        Object rvt=jp.proceed(args);
        System.out.println("模拟事务结束........");
        if(rvt!=null&&rvt instanceof Integer){
            rvt=(Integer)rvt*(Integer)rvt;
        }
        return rvt;
    }
}

Well, this is a bit more complicated. The method processTx of this class has a parameter, which represents the target method. After the first output is executed, the target method must be called again to let him finish the execution and then execute the second output.

Configure xml, and then execute the test class
Write a picture description here

See the result. Same as described in the program.


NOTE: Execution (. * The Before . (..)) && args (Pass, name)
of the target returns a * represents values for any method.
The second and third means any method of any class
&& the following means restrict the parameter type of the connection point and can filter the target method.

Ok, this can only be said to be the fur of AOP. The real AOP can be a book. This is just the use of the AOP framework in spring. Reduce unnecessary coding. The writing is not specific, but at least you can understand it. Specific needs further study. Good night, am2: 18.

____jeker_chen

Published 26 original articles · won praise 1 · views 9794

Guess you like

Origin blog.csdn.net/qq_31884013/article/details/51708574