在学习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
注解运行结果 有画面了
总结:网上对于切入点、切面、织入的概念五花八门,自己大概猜了个思路以便理解,如有问题欢迎交流,开黑的话春节再说哈哈。