Java手写Spring的AOP(切面织入)小Demo--盲僧代理击飞 亚索接大实例

在学习Spring的过程中总会很迷茫,打个@Aspect注解切面功能就有了,只要脱离了框架感觉自己还是什么都没会,所以自己猜了一下切面的思路,大概写了个小Demo,欢迎交流。


涉及知识:JDK动态代理、自定义注解


设计思路:孤儿索击飞不了敌人,需要盲僧开大击飞,所以给自己的大招方法打上了
@MyBefore注解,这样盲僧识别这个注解就知道亚索大好了,执行代理击飞。

提示:注释中也有说明,请参考。


一、创建自定义注解

模拟spring的@Before,参考代码注释
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Retention(RetentionPolicy.RUNTIME)//运行时
@Target(ElementType.METHOD)//加在方法上
public @interface MyBefore {

}

二、定义一个Hero接口,让其成为原对象以及最后生成的代理对象的顶级接口。

/**
 * 顶端接口
 * @author xi.luo
 *
 */
public interface Hero {
	public void jieDa();
}

三、创建亚索对象,实现顶端接口Hero,并在接大追加@MyBefore

/**
 * 青铜亚索,需要队友代理击飞才能接大
 * @author xi.luo
 *
 */
public class YaSuo implements Hero{
	
	@MyBefore
	public void jieDa(){
		System.out.println("亚索:狂风绝息斩!!");
	}
}

四、创建王者盲僧对象,实现InvocationHandler,处理亚索的@Before注解。

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * 王者盲僧,为亚索代理击飞
 * @author xi.luo
 *
 */
public class MangSeng implements InvocationHandler{
	
	YaSuo yaSuo;
	
	MangSeng(YaSuo yaSuo){
		this.yaSuo = yaSuo;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
		//获取Yasuo类的接口信息,如果有Before注解进行击飞
		Method[] declaredMethods = YaSuo.class.getDeclaredMethods();
		
		boolean findBefore = false;
		
		//遍历找到叫 接大 的方法,再遍历寻找该方法上打没打before注解
		for(Method m:declaredMethods){
			if("jieDa".equals(m.getName())){
				Annotation[] declaredAnnotations = m.getDeclaredAnnotations();
				for(Annotation annotation:declaredAnnotations){
					if(annotation.annotationType() == MyBefore.class){
						System.out.println(annotation.annotationType());
						System.out.println("这个类加了Before注解,在方法前织入逻辑");
					findBefore = true;
					break;
					}
				}
			}
		}
		
		if(findBefore == true){
		System.out.println("盲僧击飞->->-> 神龙摆尾!   亚索,接好了!!");
		}
		
		return method.invoke(yaSuo, args);
	}
	
	
}

五、创建运行类

import java.lang.reflect.Proxy;

public class Demo001 {
	public static void main(String[] args) {
		
		//孤儿索
		YaSuo ySuo = new YaSuo();
		
		//王者盲僧托管孤儿索
		MangSeng mangSeng = new MangSeng(ySuo);
		
		//甜蜜CP组合组成
		Hero yasuoProxy = (Hero)Proxy.newProxyInstance(YaSuo.class.getClassLoader(), YaSuo.class.getInterfaces(), mangSeng);
		
		//一脚升天
		yasuoProxy.jieDa();
	}
}

运行结果贴图:

下图为无@MyBefore注解运行结果 很孤独
在这里插入图片描述
下图为有@MyBefore注解运行结果 有画面了
在这里插入图片描述

总结:网上对于切入点、切面、织入的概念五花八门,自己大概猜了个思路以便理解,如有问题欢迎交流,开黑的话春节再说哈哈。

Java Spring AOP (Aspect Oriented Programming) 是一种编程范式,它通过将应用的业务逻辑和系统关注点(如日志、事务管理等)分离,提高了代码的可维护性和复用性。下面是一个简单的Spring AOP切面(Aspect)的Demo示例: 首先,你需要在Spring配置文件中启用AOP支持,并定义一个切面(Aspect): ```xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aspectj="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 启用AOP --> <aop:aspectj-autoproxy/> <!-- 定义切面 --> <bean id="myAspect" class="com.example.MyAspect"> <!-- 配置通知(advice) --> <property name="beforeAdvice" ref="beforeAdvice"/> </bean> <!-- 定义通知 --> <bean id="beforeAdvice" class="com.example.BeforeAdvice"/> </beans> ``` 然后,创建一个`MyAspect`切面类,通常包含通知(advice),例如前置通知(BeforeAdvice): ```java import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class MyAspect { @Before("execution(* com.example.service.*.*(..))") public void beforeAdvice(JoinPoint joinPoint) { // 在方法执行前添加的操作,如日志记录 System.out.println("Method " + joinPoint.getSignature() + " is about to execute."); } } ``` 在这个例子中,`@Before`注解定义了一个前置通知,它将在`com.example.service`包下的所有方法执行前执行。 接下来,创建`BeforeAdvice`类,这是一个具体的通知实现: ```java public class BeforeAdvice { // 可能包含一些自定义逻辑,比如参数检查或资源获取 } ``` 相关问题--: 1. Spring AOP中的通知有哪些类型? 2. `@Aspect`注解在Spring AOP中的作用是什么? 3. 如何在Spring中配置切点(execution表达式)?
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值