首先说一下,因为自己还没有去研读spring的AOP的源码,只是大致知道其功能,便想着自己先手动实现一个先看看,觉得这样以后研读源码的时候会收获更多!

实现:做一个在添加注解的方法执行之前,可以先执行另一个方法。类似AOP(@Brfore),不明白的同学可以去百度下,这边只做一个简单的现实。

首先准备一个接口IEat,作为你要做的事情比如,eat():

public interface IEat {
void eat();
}

然后两个类去实现这个接口,一个是我们的主要方法(原有不可变动的功能,这边自定义了一个@DoPre注解类似于@Before)Eat,一个是我们的代理类MyProxy,代理类还需去实现InvocationHandler这个接口,并且将cook()方法放在invoker()方法前(这个方法不清楚的同学可以去百度下,他在这里是实现执行Eat中的eat()方法,这样就相当于我前置了我需要添加的方法,吃之前得先做饭):

public class Eat implements IEat {
@DoPre
@Override
public void eat() {
System.out.println("eateateat");
}
}
public class MyProxy implements InvocationHandler, IEat {
private Object object; @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
cook();
method.invoke(object);
return null;
} public MyProxy(Object object) {
this.object = object;
} @Override
public void eat() {
} private void cook() {
System.out.println("cooking");
}
}

@DoPre注解没有具体做啥,只是作为一个标记,记得加@Retention(RetentionPolicy.RUNTIME)是指运行时能通过反射找到注解:

@Retention(RetentionPolicy.RUNTIME)
public @interface DoPre {}

最后main方法作为启动器,初始化init()方法负责扫面当前包下的带有这个@DoPre注解的方法,这边的初始化写的很简单,没有去遍历其他的包和子包,一切求简,可以自己优化很多地方:

public class Test {
public static IEat eat; //start
public static void main(String[] args) {
init();
eat.eat();
} private static void init() {
Class clazz = Test.class;
String packagePath = clazz.getResource("").getPath();
String packagename = clazz.getPackage().getName();
File file = new File(packagePath);
if (file.isDirectory()) {
File[] files = file.listFiles();
assert files != null;
for (File file1 : files) {
try {
StringBuilder stringBuilder = new StringBuilder(packagename);
stringBuilder.append(".").append(file1.getName());
String s = stringBuilder.toString().replace(".class", "");
Class clazz1 = Class.forName(s);
Method[] methods = clazz1.getMethods();
for (Method method : methods) {
Annotation[] annotations = method.getDeclaredAnnotations();
for (Annotation annotation : annotations) {
                 //找到注解方法
if (annotation.toString().contains("DoPre")) {
                   //传入被代理的实例clazz1.newInstance()
IEat proxy = (IEat) Proxy.newProxyInstance(Test.class.getClassLoader(), MyProxy.class.getInterfaces(), new MyProxy(clazz1.newInstance()));
                   //注入对象
eat = proxy;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
} } }

自己本身也是个新人,所以望大佬们见谅,代码并没有写得完美,更像是演示一这个功能,但是核心思想应该是差不多的,而且越简单可以让同学理解更快,我们学习的更应该是思想!

Java通过JDK动态代理简单的实现一个AOP的更多相关文章

  1. 深度剖析java中JDK动态代理机制

    https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...

  2. [编织消息框架][JAVA核心技术]jdk动态代理

    需要用到的工具  jdk : javac javap class 反编译 :JD-GUI http://jd.benow.ca/ import java.lang.reflect.Invocation ...

  3. JDK动态代理简单小程序

    Jdk动态代理 1.动态代理使用的情况:需要在多个方法上加上相同的逻辑的时候,需要用到动态代理. 原因:在多个方法上写相同的逻辑,第一费事,第二在不用的时候维护麻烦 使用动态代理需要用到两个类:分别为 ...

  4. java之JDK动态代理

    © 版权声明:本文为博主原创文章,转载请注明出处 JDK动态代理: JDK动态代理就是在程序运行期间,根据java的反射机制自动的帮我们生成相应的代理类 优势: - 1. 业务类只需要关注业务逻辑本身 ...

  5. aop学习总结一------使用jdk动态代理简单实现aop功能

    aop学习总结一------使用jdk动态代理实现aop功能 动态代理:不需要为目标对象编写静态代理类,通过第三方或jdk框架动态生成代理对象的字节码 Jdk动态代理(proxy):目标对象必须实现接 ...

  6. Java基础-jdk动态代理与cglib动态代理区别

    JDK动态代理 此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑. 代理模式在实际使用时需要指定具体的目标对象 ...

  7. JDK动态代理简单使用(2)

    JDK动态代理使用: 使用JDK动态代理步骤: ①创建被代理的接口和类: public interface IA { void f1(String param); } public class A i ...

  8. Java基础-JDK动态代理

    JDK的动态代理依靠接口实现  代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代 ...

  9. 设计模式之动态代理(Java的JDK动态代理实现)

    先来看一下思维导图: 对于JDK的动态代理,孔浩老师说学习的方法是把它记下来. 先写一个主题接口类,表示要完成的一个主题. package com.liwei.dynaproxy; /** * 要代理 ...

随机推荐

  1. 杭电多校第二场 hdu 6315 Naive Operations 线段树变形

    Naive Operations Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 502768/502768 K (Java/Other ...

  2. java hdu A+B for Input-Output Practice (III)

    A+B for Input-Output Practice (III) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32 ...

  3. java 高薪计划

    一.基础 集合类,并发包,IO/NIO,JVM,内存模型,泛型,异常,反射,等有深入了解,最好是看过源码了解底层的设计. 二.需要全面的互联网主流技术相关知识 深入了解mysql,redis,mong ...

  4. 【Offer】[33] 【二叉搜索树的后序遍历序列】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果.如果是则返回true, 否则返回false. 假设输入的数组的任意两个数字 ...

  5. 详细的漏洞复现:Shellshock CVE-2014-6271 CVE-2014-7169

    目录 前言 漏洞原理 利用方式 复现过程 1. 环境准备 (1) 为容器配置固定IP地址 (2) 查看bash版本 2. 本地验证:测试镜像系统是否存在漏洞 3. 远程模拟验证(原理验证) (1) 查 ...

  6. 操作系统原理之I/O设备管理(第六章上半部分下)

    五.I/O软件原理 输入输出软件的总体目标是将软件组织成一种层次结构 低层软件用来屏蔽硬件的具体细节 高层软件则主要是为用户提供一个简洁.规范的界面 设备管理的4个层次: 用户层软件 ->向系统 ...

  7. TLC5615

    #include <reg51.h> #include "TLC5615.c" code uchar seven_seg[] = {0xc0, 0xf9, 0xa4, ...

  8. python接口测试(post,get)-传参(data和json之间的区别)

    python接口测试如何正确传参: POST 传data:data是python字典格式:传参data=json.dumps(data)是字符串类型传参 #!/usr/bin/env python3 ...

  9. Docker学习之docker-compose

    docker-compose 安装 1.Mac/Windows: 安装docker的时候附带安装了. 2.Linux: curl https://github.com/docker/compose L ...

  10. 【linux】【Go】Centos7安装go1.13环境

    前言     Go(又称Golang)是Google开发的一种静态强类型.编译型.并发型,并具有垃圾回收功能的编程语言. 罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pi ...