Spring Framework-04-02-AOP-Three Implementation Methods


AOP overview

AOP is implemented based on the proxy model.
AOP=Aspect Oriented Programming

Insert picture description here

Now the mainstream is OOP. Object-Oriented Programming.
AOP is a supplement to OOP.

General conditions for using OOP

  1. Mostly used for functional code rather than business code
  2. Mostly used for public functions
  • Concern:
    A concern can be a goal for a particular problem, concept, or program. For example, log records are all concerns. If the code of a concern is referenced by multiple classes or methods, the concern is called a cross-cutting concern

It can be a problem, it can be a goal

  • Aspect:
    An aspect is the modularization of a cross-cutting concern, and it is the modularization
    of the above concern

  • Joinpoint:
    A certain point in the execution of the program, such as method call or throwing an exception, etc.
    From a spatial perspective, where can you add points?

  • Advice:
    Actions that should be performed at a specific connection point. In most AOP frameworks, advice is implemented by interceptors. The same is true for Spring AOP (define when)
    from the time level.

  • Pointcut:
    Define which connection points to use for notifications. In applications, generally specify the pointcut (where) by specifying the class name, method name, or regular expression that matches the class name and method name.

  • Target:
    = Object notified by the aspect
    = Object being proxied

  • Weaving:
    applying aspects to the target object to create a new proxy object

  • Before advice (Before advice):
    notice executed before a certain connection point

  • After returning advice:
    A notice executed after a connection point is normally completed

  • Exception notification (After throwing advice):
    notification executed when the method throws an exception and exits

  • Final advice (After finally advice):
    A notice executed when a connection point exits

  • Around advice (Around advice): the advice
    surrounding a connection point, this is the most powerful type of advice

Spring Api process

Insert picture description here

The black line is the process execution process. The
blue surface and the black line point are the connecting points.


Spring AOP

Spring AOP is implemented by pure Java language

Spring AOP is different from other AOP frameworks. The purpose is not to provide the most complete AOP. Currently, it only supports the connection point of method execution; but it is tightly integrated with Spring IoC, which can help solve common problems in enterprise applications.

The function is not very powerful and has limitations.

When Spring AOP cannot meet our needs, other AOP frameworks, such as AspectJ, can be used. Spring framework can be well integrated with frameworks such as AspectJ, and they are complementary

Insert picture description here
Purple is notification. The time angle determines the order of notification.
Entry point = where to implant. The
notifier will tell the agent factory

SpringAPI traditional way

Insert picture description here

Advance notice

Project structure

Insert picture description here

Md5Advice.java pre-notification

package adivce;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

import util.Md5Encode;


//前置通知
//需要实现接口
public class Md5Advice implements MethodBeforeAdvice{
    
    

	
	//需要实现抽象方法
	//参数1:被调用方法,参数2;被调用方法的参数,参数3:被代理的对象
	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
    
    
		System.out.println("被调用的方法"+arg0.getName());
		System.out.println("被代理的对象"+arg2.getClass().getName());
		//下面才是密码加密、
		//密码是第二个参数
		//arg1[1] = Md5Encode.getMD5(arg1[1].toString().getBytes());
		System.out.println("================================");
	}

}

Test.java

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

import com.UserService;

public class Test {
    
    

	public static void main(String[] args) {
    
    
		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
		//获取想要的目标对象,(代理对象)
		UserService us = (UserService)ctx.getBean("UserServiceProxy");
		boolean result = us.login("zs", "123");
		System.out.println("main最终结果"+result);
	}

}

UserService.java proxy mode interface

package com;


//代理模式的接口
public interface UserService {
    
    
	public boolean login(String loginName, String pwd);
	//public boolean regist(String loginName, String pwd);
}

UserServiceImpl.java proxy class

package com;

import adivce.Md5Advice;
import util.Md5Encode;

//这是被代理类
public class UserServiceImpl implements UserService{
    
    
	//通过前置通知实现操作前密码的加密
	
	
	public boolean login(String loginName, String pwd) {
    
    	
		//登录的业务逻辑
		System.out.println("传过来的判断的名字是"+loginName);
		System.out.println("传过来的判断的密码是"+pwd);
		boolean result = "zs".equals(loginName) && "123".equals(pwd);
		System.out.println("登录的业务逻辑");
		return result;
	}
	
	public boolean regist(String loginName, String pwd) {
    
    
		//插入数据库之前数据需要加密
		System.out.println("注册成功");
		System.out.println("登陆成功,密码是:"+pwd);
		return true;
	}

}

Md5Encoding.java Md5 tool class

package util;

public class Md5Encode {
    
    
	public static String getMD5(byte[] source) {
    
    
		String s = null;
		char hexDigits[] = {
    
     // 用来将字节转换成 16 进制表示的字符
		'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
		try {
    
    
			java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
			md.update(source);
			byte tmp[] = md.digest(); // MD5 的计算结果是一个 128 位的长整数,
										// 用字节表示就是 16 个字节
			char str[] = new char[16 * 2]; // 每个字节用 16 进制表示的话,使用两个字符,
											// 所以表示成 16 进制需要 32 个字符
			int k = 0; // 表示转换结果中对应的字符位置
			for (int i = 0; i < 16; i++) {
    
     // 从第一个字节开始,对 MD5 的每一个字节
											// 转换成 16 进制字符的转换
				byte byte0 = tmp[i]; // 取第 i 个字节
				str[k++] = hexDigits[byte0 >>> 4 & 0xf]; // 取字节中高 4 位的数字转换,
															// >>> 为逻辑右移,将符号位一起右移
				str[k++] = hexDigits[byte0 & 0xf]; // 取字节中低 4 位的数字转换
			}
			s = new String(str); // 换后的结果转换为字符串

		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
		return s;
	}
}

Beans.xml

<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"
	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">
    
    <!-- 业务类配置 -->
    <bean id="UserServiceImpl" class="com.UserServiceImpl"/>
    <!-- 前置通知配置 -->
    <bean id="Md5Advice" class="adivce.Md5Advice"></bean>
	<!-- 代理工厂,class属性是固定的 ,.ProxyFactoryBean是代理对象-->
	<bean id="UserServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
	   <!-- 注入接口属性,value=被代理对象接口 -->
	   <property name="proxyInterfaces" value="com.UserService"></property>
	   <!-- 注入目标属性,创建被代理对象 -->
	   <property name="target" ref="UserServiceImpl"></property>
	   <!-- 配置可以加入的通知 -->
	   <property name="interceptorNames">
	       <list>
	           <value>Md5Advice</value>
	       </list>
	   </property>
	</bean>
</beans>


Post notification

A notification file was added on the basis of the pre-notification, and the Bean was modified. xml file

Project structure

Insert picture description here

ScoreAdvice.java

package adivce;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

public class ScoreAdvice implements AfterReturningAdvice{
    
    

	
	//参数1=业务逻辑方法返回值,参数2,参数3=目标对象,参数4
	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
    
    
		System.out.println(arg0);
		System.out.println(arg3);
		System.out.println("增加100己分");
		System.out.println("==========================");
		
	}

}

Beans.xml

<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"
	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">
    
    <!-- 业务类配置 -->
    <bean id="UserServiceImpl" class="com.UserServiceImpl"/>
    <!-- 前置通知配置 -->
    <bean id="Md5Advice" class="adivce.Md5Advice"></bean>
	<!-- 后通知设置 -->
	<bean id="ScoreAdvice" class="adivce.ScoreAdvice"></bean>
	
	
	
	<!-- 代理工厂,class属性是固定的 ,.ProxyFactoryBean是代理对象-->
	<bean id="UserServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
	   <!-- 注入接口属性,value=被代理对象接口 -->
	   <property name="proxyInterfaces" value="com.UserService"></property>
	   <!-- 注入目标属性,创建被代理对象 -->
	   <property name="target" ref="UserServiceImpl"></property>
	   <!-- 配置可以加入的通知 -->
	   <property name="interceptorNames">
	       <list>
	           <value>Md5Advice</value>
	           <value>ScoreAdvice</value>
	       </list>
	   </property>
	</bean>
</beans>


POJO method, based on XML

Insert picture description here

POJO method, based on annotation

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_44627608/article/details/115291195
Recommended