The underlying implementation principle of Spring AOP

foreword

AOP is also a relatively important content in Spring. Compared with the traditional OOP mode, AOP has many incomprehensible places. This article will introduce the implementation method of AOP and its underlying implementation, including:

  • Initial AOP
  • Basic concepts of AOP
  • AOP ( concepts ) Terminology
  • dynamic proxy
  • Introduction to notifications (pre, post, return, exception, surround)
  • Annotation-based configuration notifications
  • Application scenarios of AOP

1. What is AOP

AOP (Aspect-Oriented Programming), that is, aspect-oriented programming, it complements OOP (Object-Oriented Programming, object-oriented programming), and provides a perspective of abstract software structure different from OOP. In OOP, we use classes as Our basic unit, and the basic unit in AOP is Aspect (aspect)

Second, the basic concept of AOP

The AOP framework has the following two characteristics:

  1. Good isolation between multiple steps.
  2. Source code independence.

3. AOP concepts (AOP terminology)

Aspect/Advisors (section)

Modularization of a concern that may crosscut multiple objects. In Spring AOP, aspects can be implemented using pattern-based or @Aspect annotation-based methods.

Join point

A point during program execution. In Spring AOP, a join point always represents a method execution.

Advice

An action performed at a particular join point of an aspect. Many AOP frameworks (including Spring) use interceptors as notification models and maintain a chain of interceptors centered on join points.

Pointcut (entry point)

Find conditions for join points. Advice is associated with a pointcut expression and operates on join points that satisfy this pointcut.

Introduction

Declare additional methods or properties on a type. Spring allows introducing new interfaces (and a corresponding implementation) to any proxied object.

Target object

An object to be advised by one or more aspects. Also known as the advised object. Since Spring AOP is implemented through runtime proxies, this object is always a proxied object.

AOP proxy

The object created by the AOP framework is used to implement the aspect contract (such as notification method execution, etc.). In Spring, AOP proxies can be JDK dynamic proxies or CGLIB proxies.

Weaving

Weaving is a process, which is the process of applying aspects to the target object to create an AOP proxy object. Weaving can be performed during compilation, class loading, and runtime.

Spring AOP

1. Spring AOP is implemented in pure Java, which does not require a special compilation process. Spring AOP does not require control of the class loader hierarchy, so it is suitable for Servlet containers or application servers.

2. Spring AOP currently only supports method execution join points.

3. The way Spring implements AOP is different from other frameworks. Spring does not intend to provide the most complete AOP implementation (although Spring AOP has this capability), on the contrary, it actually focuses on providing an integration between AOP implementation and Spring IoC container to help solve problems in enterprise-level development common problem.

4. Spring AOP never intends to compete with AspectJ by providing a comprehensive AOP solution. We believe that both proxy-based frameworks such as Spring AOP or mature frameworks such as AspectJ are valuable, and they should be complementary rather than competitive.

Fourth, the underlying implementation of AOP in the Spring framework

 The bottom layer of the AOP technology of the Srping framework is also the proxy technology used. The proxy method provides two

1. Dynamic agent based on JDK

Must be interface-oriented, only classes that implement specific interfaces can generate proxy objects

2. Dynamic proxy based on CGLIB

For a class that does not implement an interface, a proxy can also be generated to generate a subclass of this class

Spring's traditional AOP adopts different proxy methods according to whether the class implements the interface

  • If the class interface is implemented, use JDK dynamic proxy to complete AOP
  • If the interface is not implemented, use CGLIB dynamic proxy to complete AOP

Simple implementation of AOP based on Spring

Note that before the explanation, let me explain one point: to use Spring AOP, to successfully run the code, it is not enough to use only the jar package provided by Spring to developers. Please download two additional jar packages from the Internet:

  1. aopalliance.jar
  2. aspectjweaver.jar

5. Realize the effect of aop notification through configuration

xml configuration

<bean id="logger" class="com.ahpome.company.utils.Logger" />
<aop:config>
	// 定义切面 aspect
	<aop:aspect id="loggerAspect" ref="logger"> 
		// 定义 切入点
		<aop:pointcut id="loggerRef" expression="execution(* com.ahpome.company..*.*(..)) and !bean(logger)" />
		// 通知 环绕通知 :around;前置通知 :before;后置通知:after;最终通知:after-returning;异常通知:after-throwing
		<aop:around method="record" pointcut-ref="loggerRef" />
	</aop:aspect>
</aop:config>
	public Object record(ProceedingJoinPoint pjp){

		Log log = new Log();

		try {
			log.setOperator("admin");
			String mname = pjp.getSignature().getName();
			log.setOperName(mname);
			Object[] args = pjp.getArgs();
			log.setOperParams(Arrays.toString(args));

			// 执行目标方法,返回的是目标方法的返回值,本例中 void
			Object obj = pjp.proceed();
			if(obj != null){
				log.setResultMsg(obj.toString());
			}else{
				log.setResultMsg(null);
			}

			log.setOperResult("success");
			System.out.println("1111");

			return obj;
		} catch (Throwable e) {
			log.setOperResult("failure");
			log.setResultMsg(e.getMessage());
		} finally{
			// logService.saveLog(log);
		}
		// 注意:这里如果是返回null即使你调用的时候返回是null,即使你的方法中含有返回值
		return null;
	}

JDK dynamic proxy

	/*
	 * 接口
	 */
	public interface UserService {
		void save();
		int select();
	}
    /*
	 * 接口实现类
	 */
	public class UserServiceImpl implements UserService {

		@Override
		public void save() {
			System.out.println("保存用户信息成功");
		}

		@Override
		public int select() {
			System.out.println("查询用户信息成功");
			return 10;
		}
	}

	/*
	 * JDK动态代理工厂类
	 */
	public class JdkProxyFactory implements InvocationHandler {
		private Object target;
		public JdkProxyFactory(Object target) {
			this.target = target;
		}

		/**
		 * 获取代理对象,当前类继承InvocationHandler
		 */
		public Object getProxyObject() {
			return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			//添加功能
			System.out.println("增强代码,添加日志功能");
			//执行原有方法
			return method.invoke(target, args);
		}
	}

Test JDK dynamic proxy​

	@Test
	public void JdkProxyTest() {

		// 创建目标对象
		UserService userService = new UserServiceImpl();
		//创建工厂对象
		JdkProxyFactory jdkProxyFactory = new JdkProxyFactory(userService);
		UserService proxy = (UserService) jdkProxyFactory.getProxyObject();
		proxy.save();
		System.out.println("=========================");
		proxy.select();
		
	}

6. Application Scenarios of AOP

We mentioned earlier that AOP mainly applies some non-core business logic. Let’s take a look at the common application scenarios of AOP

  • monitor
  • log
  • cache
  • authentication
  • affairs
  • exception handling
  • Persistence

Summarize

The above is my summary of the underlying implementation issues of Spring AOP in Java development of large-scale Internet architecture Spring AOP implementation principles.

Guess you like

Origin blog.csdn.net/gongzi_9/article/details/126297378