Spring and use the basic concepts of AOP

About AOP

        AOP is an abbreviation for Aspect Oriented Programming, meaning: Aspect Oriented Programming , by pre-compiled during the operation mode and dynamic agent technology to implement a unified program functions maintenance. AOP is OOP continuation, is a hot spot in software development, but also Spring an important element of the framework is the functional programming a Yansheng Fan type. AOP can use to isolate each part of the business logic such that the business logic portions between coupling reduction, improve the reusability of the program, while improving efficiency (Baidu Encyclopedia) developed.

       Own understanding: and OOP contrast (AOP occur it is relative to the OOP) , aspect-oriented AOP, traditional OOP development code logic in a top-down , and these processes will produce some cross-cutting issues , these cross-cutting issues and our main business logic has little to do , these cross-cutting issues will not affect the main logic implementation (that is to delete the cross-cutting issues in the code inside the main logic is not affected ) , but will be scattered to various parts of the code, it is difficult to maintain . AOP is to deal with some cross-cutting issues, AOP programming idea is to separate these issues and the main business logic, business logic with the main purpose of decoupling, the higher development efficiency and reusability of code.

example:

                                          

        In the first version, a typical OOP model, a top-down calls, during which, for convenience of the system problem occurs, locate and troubleshoot the problem, we need some log output in the respective layers, or Some have permission requirements, you need to verify some of the privileges, but like logs and authority will verify doping code inside our business, lead to code a bit confusing, is not easy to maintain, such as logs and permissions verification that is, cross-cutting issues, it is important that you say, they remove the primary business logic is still on, it is not important, none of these things really can not.

                            

        In the second edition, the authority verification and logging pulled into a method, and then call the method validation and logging rights in the main business code on it, but this is still a problem, is the need for each business methods there are calls about these methods, can not be cross-cutting issues and the main business logic decoupling, this can make the code more obvious scalability and maintenance, so the third edition came out.

                            

       In the third edition, the authority is to verify and make a log section, and then dynamically injected into the place for it, this is the aspect-oriented programming, so we just need to focus on specific business on the line, do not need consider other issues.

       AOP in learning, to know the concept of AOP, which is very important, here's a look at the concept of AOP.

AOP concepts

      Joinpoint (connection points): Method in the target object, JoinPoint emphasized that attention and enhanced methods

      Pointcut (cut-off point): cut-off point represents the set of connection points, PointCut is JoinPoint predicate, which is an action, a notification is to tell the connection point where the tangent point expression to determine the number of JoinPoint (pointcut can be understood as a table , Joinpoint understood to record in the table)

      Weaving (weaving): the proxy logic is added to the process on the target object is called weaving

      Target (Audience): the original object, that object needs to be enhanced

      Aspect (section): Aspect logic is crosscutting concerns modular packaging system AOP concepts entity. Similar to a class declaration in Java, in Aspect can contain multiple Pointcut Advice and related definitions.

      Advice(通知):Advice 定义了将会织入到 Joinpoint 的具体逻辑和位置,根据位置不同可以将通过Advice分为下面几种:

Before 连接点执行之前,但是无法阻止连接点的正常执行,除非该段执行抛出异常
After  连接点正常执行之后,执行过程中正常执行返回退出,非异常退出
After throwing  执行抛出异常的时候
After (finally)  无论连接点是正常退出还是异常退出,都会执行
Around advice: 围绕连接点执行,例如方法调用。这是最有用的切面方式。around通知可以在方法调用之前和之后执行自定义行为。它还负责选择是继续加入点还是通过返回自己的返回值或抛出异常来快速建议的方法执行。

 AOP实现

       AOP是一种思想和理念,可以使用这种思想来简化代码开发的耦合性和难度,有句话说的好,天上飞的理念,必有落地的实现,那么实现了AOP这个思想的具体实现由Spring AOP和AspectJ技术,他们都是根据AOP的思想实现的。

       Spring AOP和AspectJ的关系?
       springAop、AspectJ都是Aop的实现,Spring AOP使用XML的格式进行配置的,SpringAop有自己的语法,但是语法复杂,所以SpringAop借助了AspectJ的注解(记住只是使用到了AspectJ的注解,而进行注解的解析工作是Spring内部实现的,所以Spring AOP只是借助了AspectJ的注解而已)。

spring AOP提供两种编程风格

@AspectJ support ------------>利用aspectj的注解

Schema-based AOP support ----------->xml aop:config 命名空间

证明:spring通过源码分析,我们可以知道spring底层使用的是JDK或者CGLIB来完成的代理,并且在官网上spring给出了aspectj的文档,和springAOP是不同的

     springAop的底层技术

  JDK动态代理 CGLIB代理
编译时期的织入还是运行时期的织入? 运行时期织入 运行时期织入
初始化时期织入还是获取对象时期织入? 初始化时期织入 初始化时期织入

 Spring AOP使用案例:

        关于Spring AOP的使用,Spring官网是推荐使用AspectJ来进行的,下面使用AspectJ注解来实现一个Spring AOP的例子。

        需要被增强的类:

package com.luban.aop.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
	public String getName(){
		System.out.println("getName");
		return "wj";
	}
	public void sayHello(){
		System.out.println("hello");
	}
}

      1.启用@AspectJ支持

       想要在Spring中使用AspectJ的注解,就需要在使用Java @Configuration启用@AspectJ支持,请添加@EnableAspectJAutoProxy(如果你是使用XML aop:config命名空间的形式,而不是使用AspectJ注解可以不这样进行配置)。

package com.luban.aop;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {

}

        使用XML配置启用@AspectJ支持要使用基于xml的配置启用@AspectJ支持,可以使用aop:aspectj-autoproxy元素

<aop:aspectj-autoproxy/>

       2、声明一个Aspect

      申明一个@Aspect注释类,并且定义成一个bean交给Spring管理。

package com.luban.aop;
import org.aspectj.lang.annotation.Aspect;//这是aspectj的注解
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MyAspect {
}

        3、申明一个pointCut

        切入点表达式由@Pointcut注释表示。切入点声明由两部分组成:一个签名包含名称和任何参数,以及一个切入点表达式,该表达式确定我们对哪个方法执行感兴趣。

@Pointcut("execution(* com.luban.aop.service..*.*(..))")// 切入点表达式
    public void pointcut() {// 切入点签名
}

         切入点确定感兴趣的 join points(连接点),从而使我们能够控制何时执行通知。Spring AOP只支持Spring bean的方法执行 join points(连接点),所以您可以将切入点看作是匹配Spring bean上方法的执行。

package com.luban.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 申明Aspect,并且交给spring容器管理
 */
@Component
@Aspect
public class MyAspect {
    /**
     * 申明切入点,匹配UserDao所有方法调用
     * execution匹配方法执行连接点
     * within:将匹配限制为特定类型中的连接点
     * args:参数
     * target:目标对象
     * this:代理对象
     */
	@Pointcut("execution(* com.luban.aop.service..*.*(..))")
	public void pointcut() {
	}

}

        4、申明一个Advice通知

       advice通知与pointcut切入点表达式相关联,并在切入点匹配的方法执行@Before之前、@After之后或前后运行。

package com.luban.aop;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
 * 申明Aspect,并且交给spring容器管理
 */
@Component
@Aspect
public class MyAspect {
    /**
     * 申明切入点,匹配UserDao所有方法调用
     * execution匹配方法执行连接点
     * within:将匹配限制为特定类型中的连接点
     * args:参数
     * target:目标对象
     * this:代理对象
     */
	@Pointcut("execution(* com.luban.aop.service..*.*(..))")
	public void pointcut() {
	}
    /**
     * 申明before通知,在pintCut切入点前执行
     * 通知与切入点表达式相关联,
     * 并在切入点匹配的方法执行之前、之后或前后运行。
     * 切入点表达式可以是对指定切入点的简单引用,也可以是在适当位置声明的切入点表达式。
     */
	@Before("pointcut()")
	public void before() {
		System.out.println("before advice");
	}

	@After("pointcut()")
	public void after() {
		System.out.println("after advice");
	}
}

        5.进行测试

public class Test01 {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
		UserService bean = context.getBean(UserService.class);
		bean.getName();
		bean.sayHello();
	}
}
//其打印结果:
//before advice
//getName
//after advice
//before advice
//hello
//after advice

对比:

       对于上面的例子对照着AOP的概念来说:

  • UserService 类中的getName和sayHello方法,每次被调用时所处的程序执行点都是一个 Jointpoint
  • Pointcut 就是用于指定Jointpoint集合的表达式,当然这个表达式还可以指定很多其他的接口,表达式常见的格式为:“http://execution(* com.luban.aop.service..*.*(..))”
  • Aspect 是定义 Advice、Pointcut 的地方
  • Advice 就是我们要在 哪些Jointpoint的哪个位置执行什么逻辑,MyAspect 类上面的before和after方法(加上其方法上面的注解)都是Advice ,拿before来说,@Before("pointcut()")指定了需要在哪些Jointpoint的哪个位置了,而具体的逻辑是使用before方法内部的代码来表示。
  • Weaving 就是指将before和after方法逻辑加到getName和sayHello方法的过程
  • Target 值得就是UserService这个类

 整体图:

                  

发布了230 篇原创文章 · 获赞 43 · 访问量 6万+

Guess you like

Origin blog.csdn.net/qq_35634181/article/details/104711178